Java 8 Date Time API Changes

A big part of the developer community had complained about Date and Calendar classes. The reasons were many such as hard to understand, hard to use, and not being flexible. Date class had become obsolete, and java docs suggested using Calendar class. And on top of all, date comparison was buggy.

Moving forward, Java 8 is expected to release the new Date and Time APIs/classes (JSR-310), called ThreeTen, which will change how you have been handling dates in Java. 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 core public classes are immutable and thread-safe
  • Defined terminology and behavior that other areas in computing can adapt

1. Core Classes to Represent Date and Time

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

1.1. LocalDate

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

LocalDate localDate = LocalDate.now();

System.out.println(localDate.getDayOfWeek().toString()); //WEDNESDAY
System.out.println(localDate.getDayOfMonth());           //15
System.out.println(localDate.getDayOfYear());            //135
System.out.println(localDate.isLeapYear());              //false

1.2. LocalTime

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

//LocalTime localTime = LocalTime.now();     //toString() in format 09:57:59.744
LocalTime localTime = LocalTime.of(12, 20);

System.out.println(localTime.toString());    //12:20
System.out.println(localTime.getHour());     //12
System.out.println(localTime.getMinute());   //20
System.out.println(localTime.getSecond());   //0
System.out.println(localTime.MIDNIGHT);      //00:00
System.out.println(localTime.NOON);          //12:00

1.3. LocalDateTime

The LocalDateTime class represents a date-time. There is no representation of a time zone. It represents the date and time in the current time zone.

LocalDateTime localDateTime = LocalDateTime.now();

System.out.println(localDateTime.toString());      //2013-05-15T10:01:14.911
System.out.println(localDateTime.getDayOfMonth()); //15
System.out.println(localDateTime.getHour());       //10
System.out.println(localDateTime.getNano());       //911000000

1.4. OffsetDateTime and ZonedDateTime

If you want to use the date functionality with timezone information, then the new API provides 2 classes similar to the above one i.e. OffsetDateTime and ZonedDateTime.

  • OffsetDateTime represents the date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system.
  • ZonedDateTime represents the date-time with a time-zone in the ISO-8601 calendar system.
OffsetDateTime offsetDate = OffsetDateTime.now();
System.out.println(offsetDate);  //2023-02-07T15:10:46.260589600+05:30

ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);  //2023-02-07T15:10:46.260589600+05:30[Asia/Calcutta]

2. Core Classes to Represent Timestamp and Duration

The new API has separate classes to denote the timestamp in the current timezone and in a specified timezone. We also have separate classes to denote the difference between the two dates in a consistent manner.

2.1. Instant

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

Instant instant = Instant.now();

System.out.println(instant.toString());                                 //2013-05-15T05:20:08.145Z
System.out.println(instant.plus(Duration.ofMillis(5000)).toString());   //2013-05-15T05:20:13.145Z
System.out.println(instant.minus(Duration.ofMillis(5000)).toString());  //2013-05-15T05:20:03.145Z
System.out.println(instant.minusSeconds(10).toString());				//2013-05-15T05:19:58.145Z

2.2. Duration

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

Duration duration = Duration.ofMillis(5000);

Duration duration = Duration.ofSeconds(60);

Duration duration = Duration.ofMinutes(10);

Duration duration = Duration.ofHours(2);

Duration duration = Duration.between(Instant.now(), Instant.now().plus(Duration.ofMinutes(10)));

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

2.3. Period

To interact with humans, you need to get bigger durations presented with Period class.

Period period = Period.ofDays(6);

Period period = Period.ofMonths(6);

Period period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));

3. Utility Classes and 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 that work on top of these enums. We are taking an example of such a class DayOfWeek. This class is a wrapper of day enums and can be used consistently with other classes.

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

//day-of-week to represent, from 1 (Monday) to 7 (Sunday)
System.out.println(DayOfWeek.of(2));        			//TUESDAY 

DayOfWeek day = DayOfWeek.FRIDAY;
System.out.println(day.getValue());         			//5

LocalDate localDate = LocalDate.now();
System.out.println(localDate.with(DayOfWeek.MONDAY));  //2013-05-13  i.e. when was monday in current week ?

4. Date Adjusters

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

LocalDate date = LocalDate.of(2013, Month.MAY, 15);						//Today

LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(endOfMonth.toString()); 								//2013-05-31

LocalDate nextTue = date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
System.out.println(nextTue.toString());									//2013-05-21

5. Fluent API

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

//Builder pattern
OffsetDateTime offsetDateTime = Year.of(2013)
      .atMonth(Month.MAY).atDay(15)
      .atTime(0, 0)
      .atOffset(ZoneOffset.of("+03:00"));


//factory method
OffsetDateTime date2 = OffsetDateTime.of(2013, 5, 15, 0, 0, 0, 0, ZoneOffset.of("+03:00"));

6. System Clock

A new class Clock is proposed in the new release. This simulates the system clock functionality.While doing unit testing, you are often required to test an API on future dates. For this, we had been forwarding the system clock for the next date, and then again restarting the server and testing the application.

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

Clock clock = Clock.systemDefaultZone();
System.out.println(clock);            //SystemClock[Asia/Calcutta]
System.out.println(clock.instant().toString()); //2013-05-15T06:36:33.837Z
System.out.println(clock.getZone());      //Asia/Calcutta
 
Clock anotherClock = Clock.system(ZoneId.of("Europe/Tiraspol"));
System.out.println(anotherClock);           //SystemClock[Europe/Tiraspol]
System.out.println(anotherClock.instant().toString());  //2013-05-15T06:36:33.857Z
System.out.println(anotherClock.getZone());       //Europe/Tiraspol
 
Clock forwardedClock  = Clock.tick(anotherClock, Duration.ofSeconds(600));
System.out.println(forwardedClock.instant().toString());  //2013-05-15T06:30Z

7. Timezone

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.
System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isDaylightSavings(Instant.now()));
System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isFixedOffset());

8. Format a Date

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

DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder();
formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME).appendLiteral("-").appendZoneOrOffsetId();

DateTimeFormatter formatter = formatterBuilder.toFormatter();

System.out.println(formatter.format(ZonedDateTime.now()));

These are major changes that I was able to identify and work on.

Happy Learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode