Java 8 DateTime API


Содержание

Java 8 date api

категория
Java
дата 11.07.2014
автор AliakseiBoole
голосов 19

Долгое время то, как реализована работа времени и даты в Java, было отличным поводом для шуток и издевок со стороны адептов других языков программирования. Вот только краткий список тех проблем, с которыми приходилось сталкиваться раньше:

  • Счёт времен не пойми что. К примеру, в java.util.Date дни начинаются с 0, а в java.uti.Calendar уже с 1, а первый день недели — воскресенье.
  • Отсутсвие простого и внятного API для рутинных операций по изменению времени.
  • Отсутсвие нормальной поддержки временных зон и других календарей, кроме Грегорианского.
  • Потоконебезопасность.
  • Отсутвие поддержки из коробки большого количества форматов дат.

Осознавая всю неудобность стандартного API со временем, комьюнити Java создали свое, которое было реализовано в такой популярной библиотеке как Joda-time.

И вот компания Oracle, одумавшись, создало новое API для работы с датами и временем. Чтобы не придумывать очередной велосипед, они пригласили к сотрудничеству Стивена Колборна, одного из разработчиков Joda-time.

Хватит истории, пора переходить к практике. Если вы до этого использовали Joda-time, то ничего особо нового не узнаете.

LocalDate, LocalTime и LocalDateTime

Основными объектами нового API стали классы LocalDate, LocalTime и LocalDateTime (последний является этаким объединением двух предыдущих). Официальная документация oracle советует представлять эти классы как календарь или часы на стене возле вас.

Для начала создадим пару объектов этих классов и посмотрим, что нам вернет их toString():

Судя по принтингу, нас не обманули, текстовое представление объектов действительно похоже на календарь или часы на столе. По мне это очень удобно.

Объект LocalDateTime можно получить слиянием первых двух объектов:

Также объект LocalDateTime можно получить из localDate добавлением времени в формате int:

Теперь попробуем изменить формат вывода данных, чтобы день, месяц и год представлялись в привычной стилистике (30.04.2014):

Как видно из кода, если мы попробуем отформатировать localTime, то будет выброшено исключение UnsupportedTemporalTypeException, так как это время дня, и оно ничего не знает о том, какой сейчас месяц, день и год. Более подробно о том, какие уже форматеры доступны из коробки, и какие паттерны можно использовать, вы всегда можете посмотреть в официальной документации [ЧИТАТЬ ТУТ ПРО DateTimeFormatter]. Поэтому не будем на этом долго останавливаться.

Настало время попробовать поизменять значения наших дат:

Как видно из листинга, это делать стало легко, просто и понятно. И если вы внимательно смотрели на пример, то сразу обратили внимание, что я без всяких проблем смог прибавлять и отнимать разные значения, чтобы в конце получить ту же дату!

Обращаю ваше внимание на следующий факт: ОБЪЕКТЫ В НОВОМ API ЯВЛЯЮТСЯ IMMUTABLE (НЕИЗМЕНЯЕМЫМИ)! Поэтому не стоит слишком злоупотреблять вычислениями значений времени в циклах.

А теперь попробуем поработать с датами как нормальные люди! И вычислим, каким днём будет следующий понедельник:

Если заюзать такую замечательную возможность Java как static imports, то наш код превращается чуть ли не в предложение на чистом английском языке.

Instant

Объекты этого класса хранят миллисекунды с 01.01.1970 и являются местным эквивалентом старого доброго java.util.Date. Вот пару аналогий на тему, что с ним можно делать:

ZonedDateTime

Класс аналог GregorianCalendar необходим для работы с часовыми поясами. Очень удобная вещь! Я сам из Минска, поэтому давайте посчитаем время в Минске с учетом временной зоны, а затем рассчитаем, какое сейчас время в Москве, после чего преобразуем его в LocalDateTime:

Period

Вот ещё одна очень модная и клевая фишка нового API. Позволяет прозрачно и удобно отсчитывать время от какой-то точки. Например, расчитаем, сколько мне сейчас лет:

Chronologies

Классы данного типа необходимы для разработки с использованием не ISO календарей, поэтому для большинства разработчиков они интереса не представляют. Классы данного типа могут понадобиться, на мой взгляд, в двух случаях:

  • Вы ведёте разработку для военных, есть необходимость вести отсчет, в оперативном времени.
  • Вы живёте в стране наподобие КНР и вам нужно производить перерасчет из даты ISO в дату календаря Чучхе.

API и JDBC

ANSI SQL Java SE 8
DATE LocalDate
TIME LocalTime
TIMESTAMP LocalDateTime
TIME WITH TIMEZONE OffsetTime
TIMESTAMP WITH TIMEZONE OffsetDateTime

Таблица взята из официальной документации и показывает, к какому типу SQL может быть приведён объект нового временного пакета

Всё описанное в данной статье не является полным и подробным руководством, а лишь описывает основные возможности. Чтобы полностью осознать и научиться мастерски пользоватся новым API, нужно написать не одну программу и прочитать не один мануал и статью. Так что да пребудет с вами сила.

Если Вам понравилась статья, проголосуйте за нее

A deeper look into the Java 8 Date and Time API

Within this post we will have a deeper look into the new Date/Time API we get with Java 8 (JSR 310). Please note that this post is mainly driven by code examples that show the new API functionality. I think the examples are self-explanatory so I did not spent much time writing text around them :-)

Let’s get started!

Working with date and time objects

All >java.time package. The first >java.time.LocalDate . A LocalDate represents a year-month-day date without time. We start with creating new LocalDate instances:


LocalTime and LocalDateTime are the next >LocalDate . A LocalTime works with time (without dates) while LocalDateTime combines date and time in one class:

From LocalDate / Time objects we can get all sorts of useful information we might need. Some examples:

Some information can be obtained without prov >Year class if we need information about a specific year:

We can use the plus and minus methods to add or subtract specific amounts of time. Note that these methods always return a new instance (Java 8 date/time classes are immutable).

TemporalAdjusters are another nice way for date manipulation. TemporalAdjuster is a single method interface that is used to separate the process of adjustment from actual date/time objects. A set of common TemporalAdjusters can be accessed using static methods of the TemporalAdjusters class.

Static imports make this more fluent to read:

Time zones

Timestamps

>LocalDate and ZonedDateTime prov >Instant >Instant counts the time beginning from the first second of January 1, 1970 (1970-01-01 00:00:00) also called the EPOCH. Instant values can be negative if they occured before the epoch. They follow ISO 8601 the standard for representing date and time.

Periods and Durations

Period and Duration are two other important >Period uses date based values (years, months, days) while a Duration uses seconds or nanoseconds to define an amount of time. Duration is most suitable when working with Instants and machine time. Periods and Durations can contain negative values if the end point occurs before the starting point.

Formatting and parsing

Formatting and parsing is another big topic when working with dates and times. In Java 8 this can be accomplished by using the format() and parse() methods:

Conversion between different date / time objects

Of course we do not always have objects of the type we need. Therefore, we need an option to convert different date/time related objects between each other. The following examples show some of the possible conversion options:

With Java 8 we get a very rich API for working with date and time located in the java.time package. The API can completely replace old >java.util.Date or java.util.Calendar with newer, more flexible classes. Due to mostly immutable classes the new API helps in building thread safe systems.

The source of the examples can be found on GitHub.

Java Date and Time API in Java 8 — Tutorial

Java Date and Time API. This article explains the date and time API introduced in Java 8.

1. Java 8 Date and Time API introduction

The Java language provides direct support for time-based objects. The Java 8 release contained a new API based on immutable-value classes, which are thread-safe. These classes provide a fluent API for constructing instances of them.

The java.time.LocalDate and the java.time.LocalTime classes provide a representation of date and time without timezones. They represent date and time from the context of an observer, such as a calendar on a desk or a clock on your wall.

java.time.LocalDateTime represents both a date and a time.

The following snippet demonstrates the usage these classes.

Differences between Java 8 Date Time API (java.time) and Joda-Time

I know there are questions relating to java.util.Date and Joda-Time. But after some digging, I couldn’t find a thread about the differences between the java.time API (new in Java 8, defined by JSR 310) and Joda-Time.

I have heard that Java 8’s java.time API is much cleaner and can do much more than Joda-Time. But I cannot find examples comparing the two.

  • What can java.time do that Joda-Time cannot?
  • What can java.time do better than Joda-Time?
  • Is the performance better with java.time?

2 Answers 2

Common features

a) Both libraries use immutable types. Joda-Time also offers additional mutable types like MutableDateTime .

b) Furthermore: Both libraries are inspired by the design study «TimeAndMoney» from Eric Evans or ideas from Martin Fowler about domain driven style so they strive more or less for a fluent programming style (although not always perfect ;-)).

c) With both libraries we get a real calendar date type (called LocalDate ), a real wall time type (called LocalTime ) and the composition (called LocalDateTime ). That is a very big win compared with old java.util.Calendar and java.util.Date .

d) Both libraries use a method-centric approach meaning they encourage the user to use getDayOfYear() instead of get(DAY_OF_YEAR) . This causes a lot of extra methods compared with java.util.Calendar (although latter is not type-safe at all due to excessive use of ints).

Performance

See the other answer by @OO7 pointing to the analysis of Mikhail Vorontsov although point 3 (exception catching) is probably obsolete — see this JDK-bug. The different performance (which is in general favour of JSR-310) is mainly due to the fact that the internal implementation of Joda-Time always use a machine-time-like long-primitive (in milliseconds).

Null

Joda-Time often use NULL as default for system timezone, default locale, current timestamp etc. while JSR-310 almost always rejects NULL values.

Precision


JSR-310 handles nanosecond precision while Joda-Time is limited to millisecond precision.

Supported fields:

An overview about supported fields in Java-8 (JSR-310) is given by some classes in the temporal-package (for example ChronoField and WeekFields) while Joda-Time is rather weak on this area — see DateTimeFieldType. The biggest lack of Joda-Time is here the absence of localized week-related fields. A common feature of both field implementation design is that both are based on values of type long (no other types, not even enums).

Enum

JSR-310 offers enums like DayOfWeek or Month while Joda-Time does not offer this because it was mainly developed in years 2002-2004 before Java 5.

Zone API

a) JSR-310 offers more timezone features than Joda-Time. Latter is not able to yield a programmatical access to the history of timezone offset transitions while JSR-310 is capable to do this.

b) For your information: JSR-310 has moved its internal timezone repository to a new location and a different format. The old library folder lib/zi does not exist any more.

Adjuster vs. Property

JSR-310 has introduced the TemporalAdjuster -interface as a formalized way to externalize temporal calculations and manipulations, especially for library or framework-writers this is a nice and relative easy way to embed new extensions of JSR-310 (a kind of equivalent to static helper classes for former java.util.Date ).

For most users however, this feature has very limited value because the burden to write code is still with the user. Built-in solutions based on the new TemporalAdjuster -concept are not so many, there is currently only the helper class TemporalAdjusters with a limited set of manipulations (and the enums Month or other temporal types).

Цукерберг рекомендует:  Лучший способ получить названия колонок таблицы

Joda-Time offers a field-package but practice has shown evidence that new field implementations are very hard to code. On the other side Joda-Time offers so-called properties which make some manipulations much easier and more elegant than in JSR-310, for example property.withMaximumValue().

Calendar systems

JSR-310 offers 4 extra calendar systems. The most interesting one is Umalqura (used in Saudi Arabia). The other 3 are: Minguo (Taiwan), Japanese (only the modern calendar since 1871!) and ThaiBuddhist (only correct after 1940).

Joda-Time offers an Islamic calendar based on calculatory base — not a sighting-based calendar like Umalqura. Thai-Buddhist is also offered by Joda-Time in a similar form, Minguo and the japanese one not. Otherwise Joda-Time offers coptic and ethiopic calendar, too (but without any support for internationalization).

More interesting for Europeans: Joda-Time also offers a Gregorian, Julian and mixed-gregorian-julian calendar. However, the practical value for real historical calculations is limited because important features like different year starts in date history are not supported at all (the same criticism is valid for old java.util.GregorianCalendar ).

Other calendars like Hebrew or Persian or Hindu are completely missing in both libraries.

Epoch days

JSR-310 has the class JulianFields while Joda-Time (version 2.0) offers some helper methods in the class DateTimeUtils.

Clocks

JSR-310 has no interface (a design mistake) but an abstract class java.time.Clock which can be used for any clock dependency injection. Joda-Time offers the interface MillisProvider and some helper methods in DateTimeUtils instead. So this way Joda-Time is also capable of supporting test-driven models with different clocks (mocking etc.).

Duration arithmetic

Both libraries support the calculation of time distances in one or more temporal units. However, when handling single-unit-durations the JSR-310-style is obviously nicer (and long-based instead of using int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

Handling of multiple-unit-durations are also different. Even the calculation results can differ — see this closed Joda-Time issue. While JSR-310 use a very simple and limited approach to use just the classes Period (duration based on years, months and days) and Duration (based on seconds and nanoseconds), Joda-Time uses a more sophisticated way using the class PeriodType in order to control in which units a duration (Joda-Time call it «Period») shall be expressed. While the PeriodType -API is somehow awkward to use a similar way is not offered by JSR-310 at all. Especially it is not yet possible in JSR-310 to define mixed date and time durations (based on days and hours for example). So be warned if it comes to migration from one library to another. The libraries in discussion are incompatible — despite of partially same class names.

Intervals

JSR-310 does not support this feature while Joda-Time has limited support. See also this SO-answer.

Formatting and Parsing

Best way to compare both libraries is to view the equal-named classes DateTimeFormatterBuilder (JSR-310) and DateTimeFormatterBuilder (Joda-Time). The JSR-310-variant is a little bit more powerful (can also handle any kind of TemporalField provided the field implementor has managed to code some extension points like resolve()). Most important difference is however — in my opinion:

JSR-310 can much better parse timezone names (format pattern symbol z) while Joda-Time could not do this at all in its earlier versions and now only in a very limited way.

Another advantage of JSR-310 is support for standalone month names which is important in languages like Russian or Polish etc. Joda-Time has no access to such resources — not even on Java-8 platforms.

The pattern syntax in JSR-310 is also more flexible than in Joda-Time, allows for optional sections (using square brackets), is more orientated towards CLDR-standard and offers padding (letter symbol p) and more fields.

Otherwise it should be noted that Joda-Time can format durations using PeriodFormatter. JSR-310 cannot do this.

Hope this overview helps. All the gathered information is mainly there due to my efforts and investigations how to design and implement a better date-and-time library (nothing is perfect).

Update from 2015-06-24:

Meanwhile I have found the time to write and publish a tabular overview for different time libraries in Java. The tables also contain a comparison between Joda-Time v2.8.1 and Java-8 (JSR-310). It is more detailed than this post.

Java 8 – Date and Time Examples

By Lokesh Gupta | Filed Under: Java 8

A big part of developer community has been complaining about Date and Calendar classes. Reasons were many such as hard to understand, hard to use and not flexible. Date class has even become obsolete and java docs suggest to use Calendar class instead of Date class. And on top of all, Date comparison is buggy and I have also faced such issue in past.


Moving forward, JAVA 8 (Lambda) is expected to release the new Date and Time APIs/classes (JSR-310), also called as ThreeTen, which will simply change the way you have been doing till date. This A key part of this is providing a new API that is dramatically easier to use and less error prone.

It will provide some highly demanded features such as:

    All the key public >I wrote this post on 15th May 2013. Now today on 18th Mar 2014, java 8 is finally released and available for early access. I have re-validated and verified all the outputs in post examples. They work like charm as they did in May last year. Only change encountered was in TemporalAdjuster.java . Previously it was a class, now it is a @FunctionalInterface . So, I have corrected the related example and used the class “ TemporalAdjusters.java “.

New classes to represent local date and timezone

The new classes intended to replace Date class are LocalDate , LocalTime and LocalDateTime .

LocalDate

The LocalDate class represents a date. There is no representation of a time or time-zone.

LocalTime

The LocalTime class represents a time. There is no representation of a date or time-zone.

LocalDateTime

The LocalDateTime class represents a date-time. There is no representation of a time-zone.

If you want to use the date functionality with zone information, then Lambda provide you extra 3 classes similar to above one i.e. OffsetDate , OffsetTime and OffsetDateTime . Timezone offset can be represented in “+05:30” or “Europe/Paris” formats. This is done via using another class i.e. ZoneId .

New classes to represent timestamp and duration

Instant

For representing the specific timestamp ant any moment, the class needs to be used is Instant. The Instant class represents an instant in time to an accuracy of nanoseconds. Operations on an Instant include comparison to another Instant and adding or subtracting a duration.

Duration

Duration class is a whole new concept brought first time in java language. It represents the time difference between two time stamps.

Duration deals with small unit of time such as milliseconds, seconds, minutes and hour. They are more suitable for interacting with application code.

Period

To interact with human, you need to get bigger durations which are presented with Period class.

Added utility classes over existing enums

The current Java SE platform uses int constants for months, day-of-week and am-pm etc. Now a lot of extra utility classes have been added which work on top of these enums. I am taking an example such a class DayOfWeek. This class is a wrapper of day enums and can be used consistently with other classes also.

DayOfWeek

Other such classes are Month , MonthDay , Year , YearMonth and many more.

Date adjusters

Date adjusters are another beautiful and useful addition in date handling tools. It easily solves the problems like : How do you find last day of the month? Or the next working day? Or a week on Tuesday?

Lets see in code.

Creating date objects

Creating date objects now can be done using builder pattern also. The builder pattern allows the object you want to be built up using individual parts. This is achieved using the methods prefixed by “at”.

New class to simulate system/machine clock

A new class Clock is proposed in new release. This simulates the system clock functionality. I loved this feature most of all others. The reason is while doing unit testing. you are often required to test a API in future date. For this we had been forwarding the system clock for next date, and then again restart the server and test the application.

Now, no need to do this. Use Clock class to simulate this scenario.

Timezone Changes

Timezone related handling is done by 3 major classes. These are ZoneOffset, TimeZone, ZoneRules.

  • The ZoneOffset class represents a fixed offset from UTC in seconds. This is normally represented as a string of the format “±hh:mm”.
  • The TimeZone class represents the identifier for a region where specified time zone rules are defined.
  • The ZoneRules are the actual set of rules that define when the zone-offset changes.

Date Formatting

Date formatting is supported via two classes mainly i.e. DateTimeFormatterBuilder and DateTimeFormatter . DateTimeFormatterBuilder works on builder pattern to build custom patterns where as DateTimeFormatter provides necessary input in doing so.

These are major changes which I was able to identify and worked on.

Java 8 Date and Time API Tutorial


Posted by: Nawazish Khan in Time August 1st, 2020 0 Views

JDK 1.0 had java.util.Date class giving access to Java’s first Date API. However soon after its usage, it started to show cracks of problems on its brittle surface. It did not take any longer to realize that java.util.Date was not thread-safe!

Table Of Contents

1. Introduction – Why yet another Date and Time API in Java

Put in a multi-threaded environment, an instance of java.util.Date class could easily become inconsistent since the mutators (setters) methods change the very state of the java.util.Date object without any proper synchronization. Even though today most of the mutator methods are deprecated, however, their mere presence itself is extremely dangerous. Following are some of the deprecated mutator methods, notice the java.lang.Deprecated annotations:

Problematic mutators in legacy Date-Time API

The problem with java.util.Date did not stop there; it was, in my humble opinion, a bit clunky to use. Take for instance its (deprecated!) public constructor:

The legacy not-so-intuitive constructor

Here the offset of year starts from 1900, therefore, if we had to instantiate a Date to represent, say, year 2020, we would code something like,

Date (116, month, date)

Quite obviously 116 is not as straight forward as 2020. Similarly, the indexing of month parameter is also not quite consistent with the general human understanding of months wherein months starts from 1 and ends on 12. However, for this constructor the months begin from 0 and end on 11! So the developer has to take that extra care of mapping January to 0, December to 11 so on and so forth! This could well be a probable cause of a painstaking bug!

Finally the String returned by default toString() implementation returns the default time zone of the JVM. So printing a java.util.Date instance would append time zone as well. Something like the following:

Wed May 04 00:00:00 IST 2020

Notice IST (Indain Standard Time) – that is the default time zone of my Hotspot . This by itself does seem to be an innocent looking naive problem, however, the problem is that it gives a false impression as if the intance of Java.util.Date class is time zone context-aware, which is simply not the case!

The JDK team did worke really hard to address all of these issues. One of their standard fix was the introduction of java.util.Calendar class. However, it also had problems with it, especially, the perennial problem of thread vulnerability. Running parallel to the java.util.Date class was java.text.DateFormat class used to format java.lang.String objects to make them parse-able into java.util.Date instances. However, as you might have guessed already, this class was also thread un-safe.

In the coming sections we would see how JDK engineers worked on these problems and gave us solution in the form of new Date and Time API!

2. The new Date and Time API

The new Date and Time API is packaged under java.time and other java.time.* packages. At the base of this API is the java.time.Temporal interface. This interface binds the basic contract as to how the states of temporal objects such as date ( java.time.LocalDate ), time ( java.time.LocalTime ), or combination of these two ( java.time.LocalDateTime ), would be accessed. Please note that this interface does not bind on its implementation to be immutable but it is nevertheless officially and strongly recommended to make it immutable (obviously for thread safety!). In the subsequent sections we would see how to use these classes.

2.1 LocalDate

The java.time.LocalDate is our first class and it is closer to the java.util.Date class in it that LocalDate encapsulates a particular date (day of month, month of year and year itself) on the time line. By itself the LocalDate class does not contain any information about a particular time (the minute, seconds, hour etc) instant, we have other alternative for doing so.

Before we move on to actually using this >

Since we have already seen the problem of intuitiveness by using one of the constructors of java.util.Date class, we would be using a public factory method from java.time.LocalDate which takes the same parameters of year, month and day of month:

Цукерберг рекомендует:  Как не стать дизайнером за 1 день

Public constructor from new Dat-Time API

The above construct would instantiate an instance of LocalDate representing a time instance of 3rd July, 2020. There is yet another convenience factory method to get a LocalDate instance representing system clock:

public static LocalDate now()

Apart from these, there are various getter methods exposed in LocalDate class to get the month, date and year properties respectively.

We would visit Month and DayOfWeek class very shortly, nevertheless, they are pretty straight forward and self explanatory.

We just saw how to get individual attributes from a LocalDate instance can be accessed; the same properties can also be fetched by passing an instance of java.time.temporal.TemporalField . java.time.temporal.ChronoField is an concrete implementation of TemporalField and its fields can be used to represent any date-time attribute. For instance, we would use ChronoField fields to fetch some of the common date attributes:

Using ChronoField to fetch attributes from LocalDate API

2.2 LocalTime

Running parallel to LocalDate is the java.time.LocalTime class. It is used to represent a particular time (without any time zone) from the time line. Thus, in order to, say, represent 04 hours, 30 minutes, and 45 seconds, we can write:

Using static factory methods of the new Date-Time API

Just like LocalDate , we have friendly getter methods in LocalTime as well; some which accept TemporalField instances and return time attributes based on the TemporalField s and others which directly return the time attribute without accepting any TemporalField instance.

2.3 Amalgamating LocalDate/Time

There are various business requirements where the date or the time alone would not fit the bill in all such situations it is desired to have one instance which could represent both date and time from the time line. The LocalDateTime class helps in this regard. It is again really straightforward to use its APIs:

Using static factory methods of the new Date-Time API

There is yet another overloaded version of LocalDateTime.of (…) which accepts instances of LocalDate and LocalTime and combines them:

API to combine Date and Time in one object

It is also possible to provide a specific time to a LocalDate instance using the atTime(. ) method:
API to convert from LocalDate to LocalDateTime

Conversely, we can also provide a date to a LocalTime instance using the atDate(. ) instance:
API to convert from LocalTime to LocalDateTime


Likewise it is also possible to separate out date and time factors as LocalDate and LocalTime instances from LocalDateTime reference:

Fetching LocalDate/Time from LocalDateTime instance

2.4 Instant

Thus far we have seen at least three date-time classes, namely, LocalDate , LocalTime , LocalDateTime . All of these help make developer’s life easy. However, the new JDK8 Date Time API has got java.time.Instant class which is meant more for the machine. All earlier classes we have seen works in terms of years, months, days, hours, minutes, seconds etc. However, the Instant class represents a date-time instant on the timeline via single large number. This number basically represents the number of seconds elapsed since the Unix epoch time conventionally set at 1st January, 1970 UTC.

With static factory methods in Instant class, its pretty straightforward to get an Instance of Instant class representing anything valid on the time line. For instance:

Using static factory method to instantiate Instant class

The above statement represents a time instance which is 5 seconds away from the Unix epoch time! There is an overloaded version of this method which takes a second argument adjusting nanoseconds to the passed number of seconds.

And in case if we need, let’s say, milliseconds elapsed since Unix epoch time we can even do that using the following API:

public static Instant ofEpochMilli(long epochMilli)

Instant class has yet another static factory method now() which provides the current time instant since the epoch time according to the system clock:

public static Instant now()

However, note that Instant class only represents seconds elapsed since epoch time, it does not support differentiating between different date-time parameters which humans understand like year, week, month, hour, minutes etc. However, in order to still work with these parameters we can use java.time.Duration and java.time.Period

2.5 Duration

All of the classes we have visited thus far have represented a particular date-time on the time line, say, t1, t2 etc. Quite naturally we might sometimes need to find the duration between two date-time instances, something like, t2-t1:

Different ways of using Duration class to get difference between two date-time instance

Since the semantics and usage of Instant class is different from LocalDate/Time/DateTime classes, it would be a java.time.temporal.UnsupportedTemporalTypeException if we try to use them together to get the Duration instance. For instance, the following usage of Duration.between(. ) is exceptional:

Duration.between(localTime, instant); // UnsupportedTemporalTypeException

The Duration class models a “time-based amount of time” between two date-time instance and as such it does not provide us with specific date-time related properties like year, month, hour etc. For such requirements, we may use another flexible API – the java.time.Period class:

Using Period clas

Using one of the convenient factory method from the Period class, we can even instantiate a Period directly, that is, without defining it as a difference between two java.time.temporal.Temporal instances.

Period twoYearsFiveMonthsOneDayPeriod = Period.of(2, 5, 1);

3. Formatting and Parsing

Thus far, we have seen quite a few date-time API from the JDK8 which helps us work with date and time instances, however, there are quite a lot use-cases wherein we would want to parse strings into dates and times. In this section we would checkout the parsing API available to us.

The java.time.format package has a class called DateTimeFormatter which facilitates in formatting to and parsing from java.lang.String to various date-time classes we have seen thus far. Before we move on into seeing DataTimeFormatter in action, we should consider the fact that this class is thread-safe and hence singleton instances of this class can be safely published to various accessing threads; on the contrary, java.text.DateFormat was not inherently thread-safe!

DateTimeFormatter class provides various standard date formatters via its static fields. These all return references of DateTimeFormatter type and can be used in conjunction with date-time APIs that we have seen. Consider for example the following case where we will format an instance of LocalDate to a particular String representation:

Using standard DateTimeFormatter

Conversely, we may parse a valid String (representing a date or time) into its corresponding LocalDate or LocalTime equivalents:
Parse pareable string to LocalDate using DateTimeFormatter

Although DateTimeFormatter provides standard formatters to parse and format, however, it also provides provisions to come up with our own custom DateTimeFormatter s using its ofPattern(. ) method:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(«dd/MM/YYYY»);

Using the above DateTimeFormatter (formatter) we can format and parse dates as follows:

Using custom DateTimeFormatter

Quite interestingly, DateTimeFormatter.ofPattern(. ) also accepts a java.util.Locale instance to cater to Local related requirements:

public static DateTimeFormatter ofPattern(String pattern, Locale locale)

4. The TemporalAdjuster

So far so good, however, there are situations when we want to perform special manipulations with date-time instances. Say, for instances, we are interested in the next working day assuming that Saturday and Sundays are non-working days. In all such situation where special date-time adjustments are required we can use the java.time.temporal.TemporalAdjuster .

TemporalAdjuster is an interface, albeit, its a functional interface with only one abstract method, namely, the Temporal adjustInto(Temporal temporal) . From the signature of this method it is easy to understand what TemporalAdjuster is meant to do! Basically, it will accept a java.time.temporal.Temporal instance (all of the classes that we have seen so far implement the Temporal interface which defines how the different date-time API are meant to be handled by the application) and after modifying the passed-in Temporal according to the business logic, the adjustInto method will return another Temporal !

Its pretty straight forward to use TemporalAdjuster instance to adjust any date-time entity! Most commonly used date-time APIs like the LocalDate or the LocalTime classes all have the with(. ) method which accepts a TemporalAdjuster instance which would adjust this date-time accordingly.

Consider the signature of TemporalAdjuster:

Next we would implement this interface to calculate the next working day.

With an implementation of TemporalAdjuster in hand, we can easily use it:
Using TemporalAdjuster with other Date-Time APIs


Lambda Lovers may use java.time.temporal.TemporalAdjusters.ofDateAdjuster(UnaryOperator dateBasedAdjuster) :

TemporalAdjuster with Lambda implementation

And then we may use this TemporalAdjuster the normal way:

For one more note, TemporalAdjusters class has some predefined utility TemporalAdjuster implementations exposed through various static factory methods that it has!

5. Time Zone

Thus far all the date-time APIs that we have seen had nothing to do with the time zones of various regions. Nevertheless, in real time software challenges, time zones play a critical role notwithstanding its complications. Therefore, in order to further abstract the complication of time zones, the new date time API provides java.time.ZoneId class as an alternative for java.util.TimeZone class.

The ZoneId class holds unique IDs representing various well-known regions across the globe. For instance, «Europe/Paris» is a valid zone id. With each time zone, there is a specific set of rules associated which guarantees that across the entire region the standard timing is going to remain the same! All such rules are encapsulated inside the java.time.zone.ZoneRules class.

With that in mind its really easy to get a reference representing a particular time zone; we may say:
Using ZoneId class via its static factory method

Then onwards its pretty straight forward to associate a time zone to a particular date. For instance:

Associating Time Zone to a LocalDate

Notice the return type of method atStartOfDay(. ) . It is java.time.ZonedDateTime . As name suggests a ZonedDateTime encapsulates all relevant information. It has Date, Time and the Time Zone (for offset calculation purposes) all embedded into it.

java.time.ZoneOffset is a subclass of ZoneId which is used to represent the time-zone offset of the given time from the standard Greenwich/UTC such as -05:00. In order to work with, simply use its static factory of(. ) method:

Using ZoneOffset class

Since New York which corresponds to US Eastern Standard Time is factually 5 hours behind the Greenwich zero meridian, newYorkOffset correctly represents it (although ZoneOffset does not take into account the Day Light Saving complications).

With ZoneOffset ready in hand we can apply it with any of the date-time APIs that we have seen earlier to manage the time zone offset differences between different regions of the world:

Using OffsetDateTime class

Notice the class java.time.OffsetDateTime . This class encapsulates the date, time and the offset difference from the standard Greenwich zero meridian!

6. Calendar

Up until JDK8, ISO-8601 was the defacto calendar system in usage. However, all around the world there are numerous other local calendar systems used, at times, very religiously by various communities across the globe. JDK8 has included four such calendar systems:

  • Japanese calendar
    Hijrah calendar (Islamic Calendar)
    Minguo calendar
    Thai Buddhist calendar

All of these new calendar systems and their respective dates are packaged under java.time.chrono package. The java.time.chrono.Chronology interface defines the various non-standard calendar systems and the java.time.chrono.ChronoLocalDate interface defines the various dates used in the Chronology calendars.

Since it seems like out of the four non-ISO calendars included, the Hijrah Calendar is most complicated as it is based on Lunar astronomy and may even have variants, for the sake of demonstration we would consider only Hijrah Calendar herein.

6.1 Chronology and ChronoLocalDate

As mentioned earlier that Chronology and ChronoLocalDate model non-ISO calendar and its corresponding dates respecticely, we would start by demonstrating their usage!

The Chronology interface has a static factory of(. ) which takes in a String parameter identifying the particular calendar system we need. These are standard identifier specified by the CLDR and Unicode Locale Data Markup Language (LDML) specifications!

Fetching a Hijrah Calendar

Once we have an instance of the calendar, we can access its dates:

Using Hijrah Calendar

However, there are dedicated Islamic calendar and dates also available via the java.time.chrono.HijrahChronology and java.time.chrono.HijrahDate classes. In the next section we would see their usage.

6.2 HijrahChronology and HijrahDate

The new Java 8 Date and Time API also provides specific extensions and implementations of Chronology and ChronoLocalDate in the form of java.time.chrono.HijrahChronology and java.time.chrono.HijrahDate respectively. HijrahChronology is based on the Islamic Hijrah calendar system which itself depends on lunar movements. The length of each month according to this calendar is judged by any authorized seeing of the new moon! Generally the length of each month is 29 or 30 days. Ordinary years have 354 days; leap years have 355 days. The HijrahDate class operates on this calendar. Below we would see some of the usages of these entities.

Using the HijrahDate API

7. Conclusion

The intial Date Time API has multiple flaws; perhaps the most glaring of them all was the design choice of making the original Date and Time APIs Thread-Unsafe! In contrast to this, the current Date and Time API with JDK8 is immutable and consequently thread safe.

Java Tutorial Network

Java Tutorials for Beginners and Professionals

Java 8 Date Time API

Java 8 introduced a new Date-Time API which purpose is to cover drawbacks of the old date-time API.

The previous date-time api was not thread safe and the replacement for the new date-time API is that it does not have any setter methods. Another drawback that is fixed by the new API is the poor design. The old API had less direct methods for date operations. And yet another drawback of the old API was that programmers had to write a lot of code to deal with timezone issues.

Цукерберг рекомендует:  CakePHP с нуля генератор Bake строит приложения с отношениями в таблицах


Not only does the new API solve all these problems, but it also introduces 2 important classes that are in java.time package:

  • Local – no complexity of timezone handling
  • Zoned – more complex date-time API that deals with various timezones

Local time API should be used when time zones are not required

An example of Local Date-Time API which uses the main method calls

Output:

Zoned Date-Time API example

Output

As you can see, Zoned Date-Time API can give you an access of a specific time zone and can also give you your time zone or the system’s default time zone.

Chrono Units Example

Output:

Period and Duration

Period deals with date based amount of time and duratioin deals with time based amount of time.

Output

The Java memory model specifies how the Java virtual machine works with the computer’s memory (RAM). In this tutorial I will show you how to…

In this tutorial I will show you how to store and retrieve values from a properties file in Java There are a number of scenarios…

This examples shows you how to iterate through a HashMap in Java Iterate over a collection or data set in Java is a very common…

Java 8 Date – LocalDate, LocalDateTime, Instant

Java 8 Date Time API is one of the most sought after change for developers. Java has been missing a consistent approach for Date and Time from start and Java 8 Date Time API is a welcome addition to the core Java APIs.

Table of Contents

Why do we need new Java Date Time API?

Before we start looking at the Java 8 Date Time API, let’s see why do we need a new API for this. There have been several problems with the existing date and time related classes in java, some of them are:

  1. Java Date Time classes are not defined consistently, we have Date Class in both java.util as well as java.sql packages. Again formatting and parsing classes are defined in java.text package.
  2. java.util.Date contains both date and time, whereas java.sql.Date contains only date. Having this in java.sql package doesn’t make sense. Also both the classes have same name, that is a very bad design itself.
  3. There are no clearly defined classes for time, timestamp, formatting and parsing. We have java.text.DateFormat abstract class for parsing and formatting need. Usually SimpleDateFormat class is used for parsing and formatting.
  4. All the Date classes are mutable, so they are not thread safe. It’s one of the biggest problem with Java Date and Calendar classes.
  5. Date class doesn’t provide internationalization, there is no timezone support. So java.util.Calendar and java.util.TimeZone classes were introduced, but they also have all the problems listed above.

There are some other issues with the methods defined in Date and Calendar classes but above problems make it clear that a robust Date Time API was needed in Java. That’s why Joda Time played a key role as a quality replacement for Java Date Time requirements.

Java 8 Date

Java 8 Date Time API is JSR-310 implementation. It is designed to overcome all the flaws in the legacy date time implementations. Some of the design principles of new Date Time API are:

  1. Immutability: All the classes in the new Date Time API are immutable and good for multithreaded environments.
  2. Separation of Concerns: The new API separates clearly between human readable date time and machine time (unix timestamp). It defines separate classes for Date, Time, DateTime, Timestamp, Timezone etc.
  3. Clarity: The methods are clearly defined and perform the same action in all the classes. For example, to get the current instance we have now() method. There are format() and parse() methods defined in all these classes rather than having a separate class for them.

All the >Java 8 Date Time API Packages

Java 8 Date Time API consists of following packages.

  1. java.time Package: This is the base package of new Java Date Time API. All the major base classes are part of this package, such as LocalDate , LocalTime , LocalDateTime , Instant , Period , Duration etc. All of these classes are immutable and thread safe. Most of the times, these classes will be sufficient for handling common requirements.
  2. java.time.chrono Package: This package defines generic APIs for non ISO calendar systems. We can extend AbstractChronology >Java 8 Date Time API Examples

We have looked into most of the important parts of Java Date Time API. It’s time now to look into most important classes of Date Time API with examples.

LocalDate

LocalDate is an immutable class that represents Date with default format of yyyy-MM-dd. We can use now() method to get the current date. We can also provide input arguments for year, month and date to create LocalDate instance. This class provides overloaded method for now() where we can pass ZoneId for getting date in specific time zone. This class provides the same functionality as java.sql.Date . Let’s look at a simple example for it’s usage.

LocalDate methods explanation is provided in comments, when we run this program, we get following output.


LocalTime

LocalTime is an immutable class whose instance represents a time in the human readable format. It’s default format is hh:mm:ss.zzz. Just like LocalDate, this class provides time zone support and creating instance by passing hour, minute and second as input arguments. Let’s look at it’s usage with a simple program.

When we run above program for LocalTime examples, we get following output.

LocalDateTime

LocalDateTime is an immutable date-time object that represents a date-time, with default format as yyyy-MM-dd-HH-mm-ss.zzz. It provides a factory method that takes LocalDate and LocalTime input arguments to create LocalDateTime instance. Let’s look it’s usage with a simple example.

In all the three examples, we have seen that if we provide invalid arguments for creating Date/Time, then it throws java.time.DateTimeException that is a RuntimeException, so we don’t need to explicitly catch it.

We have also seen that we can get Date/Time data by passing ZoneId , you can get the list of supported ZoneId values from it’s javadoc. When we run above class, we get following output.

Instant

Instant class is used to work with machine readable time format, it stores date time in unix timestamp. Let’s see it’s usage with a simple program.

Output of above program is:

Java 8 Date API Utilities

As mentioned earlier, most of the Date Time principle classes provide various utility methods such as plus/minus days, weeks, months etc. There are some other utility methods for adjusting the date using TemporalAdjuster and to calculate the period between two dates.

Output of above program is:

Java 8 Date Parsing and Formatting

It’s very common to format date into different formats and then parse a String to get the Date Time objects. Let’s see it with simple examples.

When we run above program, we get following output.

Java 8 Date API Legacy Date Time Support

Legacy Date/Time classes are used in almost all the applications, so having backward compatibility is a must. That’s why there are several utility methods through which we can convert Legacy classes to new classes and vice versa. Let’s see this with a simple example.

When we run above application, we get following output.

As you can see that legacy TimeZone and GregorianCalendar classes toString() methods are too verbose and not user friendly.

That’s all for Java 8 Date Time API, I like this new API a lot. Some of the most used classes will be LocalDate and LocalDateTime for this new API. It’s very easy to work with and having similar methods that does a particular job makes it easy to find. It will take some time from moving legacy classes to new Date Time classes, but I believe it will be worthy of the time.

Java Date and Time API in Java 8 — Tutorial

Java Date and Time API. This article explains the date and time API introduced in Java 8.

1. Java 8 Date and Time API introduction

The Java language provides direct support for time-based objects. The Java 8 release contained a new API based on immutable-value classes, which are thread-safe. These classes provide a fluent API for constructing instances of them.

The java.time.LocalDate and the java.time.LocalTime classes provide a representation of date and time without timezones. They represent date and time from the context of an observer, such as a calendar on a desk or a clock on your wall.

java.time.LocalDateTime represents both a date and a time.

The following snippet demonstrates the usage these classes.

Java 8 Date/Time API

You are using an outdated browser. Upgrade your browser today or install Google Chrome Frame to better experience this site.

Programming tutorials, problems, solutions. Always with code.

Java 8 Date Time concepts

In Java 8 Date and Time went another remodeling resulting in much better API and concepts better reflecting developer’s needs. Here we’ll go through Java 8 new Date and Time concepts.

Java history around Date/Time mess

Problems with time

Developers who write business systems often need to calculate date/time of something (e.g. a flight starts at 10:00 PM in one city and flies for 6 hours, when will it arrive? Do they have DST at that day? etc.). The rules for Earth calendars are just crazy and it’s basically impossible to handle them inside our systems. Here are some of the problems:

Timezones handling


  • Australia has horizontal and vertical timezones during summer
  • Timezone Donut in Arizona
    Arizona – no DST, Navajo Reservation – DST, Hopi Reservation inside Navajo Reservation – no DST :-)

Daylight Saving Time (with local modifications)

  • DST yes, but not during Ramadan
  • DST doesn’t start/end in full hour (e.g. India +05:30, Nepal +05:45)
  • DST moves by 1 hour, except Lord Howe Island (Australia), where it moves by 0:30
  • Greenwich (the place) is GMT+01:00 during summer :-)
  • Brazil sets its summer time by decree every year (probably during the Rio Carnival ;-) )

Leap years and seconds

Yes, there are leap seconds too, and not each and every day has the same number of seconds. All it means is that the time 23:59:60 is perfectly valid time.

Date/Time before Java 8

Before Java 8 there were not many possibilities to express time-related concepts and doing date calculations was tedious.

java.util.Date

It was introduced in 1.0 and in Java 1.1 almost all its methods were deprecated. The Date class is simple and sometimes enough when accuracy is not important and you don’t want to do any calculations on it, but there are some issues with it:

  • It is mutable (need to create defensive copies)
  • Knows nothing about Time Zones, Daylight Saving Time, leap years/seconds, etc.

java.util.Calendar

It was another attempt to add Date and Time support in Java. The class in tedious to instantiate and work with, but at least it allows to do some date/time calculations. Calendar is also mutable, doesn’t include leap seconds (for me hardly a problem) and has awkward API:

joda-time

This library became de facto standard library for time and date calculations in Java. Java 8 Date Time API is based on joda-time, but arguably more convenient.

Conceptual changes in Java 8

The Date Time API has been designed from scratch and greatly extended. There are classes that represent different date and time concepts and better fit what we do with time – set schedules, calculate periods, calculating end day of something, etc.

Important thing is that whole API follows common themes:

  • objects are immutable, thread-safe and cacheable
  • enums for months and many other items
  • day calculation strategies
  • each day always has 86400 seconds (no leap seconds).

Java 8 Date and Time representations

In this section we present the most important Java 8 classes for date and time concepts.

Instant – a point in time

Think of it as a point in space (cosmic time) – no timeones, no DSTs, no… nothing. It’s just a point on a timeline.

Some of its notable properties:

  • It is a point on a time line with nanosecond precision
  • Holds time in UTC timezone
  • Immutable and thread-safe
  • useful for representing timestamps

Example values of java.time.Instant:

LocalTime – time of day

Represents a time of day and comes with a bunch of methods to manipulate time. It’s like a meeting time – e.g. our Daily Scrum meeting starts everyday at 10:00 AM.

LocalDate – a date without time (day precision)

Represents date objects without time – e.g. event from the past.

An example of how February 29th is handled:

LocalDateTime – both in one object

Represents a date with time. For example scheduled appointment or flight departure date:

MonthDay, YearMonth, Year

Of course there are classes for individual parts of a date.

MonthDay – day of month accuracy

YearMonth – month of year accuracy

Year – year accuracy

ZonedTime, ZonedDateTime – date/time within time zone

These two classes are like LocalDate(Time), but with time zone information – date and time are expressed for selected time zone. In Java 8 there is ZoneId class for time zone objects (see How to get available time zones).

Length of time

Duration – machine time distance

It’s the duration between two Instant objects and doesn’t keep date information (day, month, year). It’s just a distance between two timestamps.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих