Java 8 Date Time API

What ailed Date and Time handling in Java?

The existing java.util.Date and SimpleDateFormat are mutable and not thread-safe, more often than not, leading to concurrency issues for users. Having to deal with this overhead is not welcoming for novice developers. Inconsistent API (months starting at 1 while days start at 0), no ability to handle Time alone, no utilities like plus/minus dates lead to popularity of libraries like joda-time. Many enterprise products use joda-time, when date/time usage and manipulation should have been provided by the language which was in it’s 7th iteration (personal opinion 🙂 )

These problems were finally addressed by JSR 310 jointly led by Oracle and joda-time author, Stephen Colebourne. Given joda-time’s success over the years, it is safe to assume that the new Java Date Time API is well written and very useful, and it indeed is.

Key pointers on the new API

Thread Safety

The entire package is immutable and thread-safe except for serialization classes and some classes used for formatting/parsing (by design). Interfaces and abstract classes also dictate that subsequent implementations must be immutable and thread-safe and final (in some cases). This ensures that there will be no inherent concurrency issues when using this API.

Better API Model

The new API offers clarity and understanding on the usage by consistency. Methods like now(), parse(), plus/minus are available in all classes like Instant, LocalDate, LocalDateTime and many more. Learn one class and you are ready to use others too.

Better Use Case Handling

The sorely missing item in java.util.Date is the ability to just store a date without a time component or vice versa. A date always has a time component (e.g. 12:00:00.000 AM) and when doing date arithmetic, mistakes are bound to happen if enough care is not taken to normalize the dates. With LocalDate and LocalTime and other classes there is freedom to store and represent the combinations that you want. Don’t forget to drop in Time-zone in this combination.

Extendable

Different calendaring systems, mentioned later in the post, supported allow for better internationalization. The extensible nature of the API allows for specifying custom clocks and calendars that serves advanced globalization use cases.

Java 8 Date Time API Packages

Let us look at some of the core classes which will give us an understanding of the kind of features made available. All these classes are immutable and thread-safe.

java.time.Clock
  • Provides access to current instant, date and time using a time-zone, utilizing the best system clock available
  • This is an optional class as all other classes offer a now() method that uses system clock with default timezone
  • The purpose is to allow alternate clocks to be plugged in as and when required.
  • E.g.
    • API provided FixedClock can be used for testing purposes
    • Custom clocks that utilize a NTP (Network Time Protocol) server to give more accurate times
java.time.Instant
  • a single point on the time-line
  • can be used as a timestamp
  • Supports 999,999,999 years before and after epoch (Woaaah!)
java.time.LocalDate
  • A date without a time/time-zone component in the ISO-8601 calendar system. E.g. 2016-01-22
  • Does not store or represent time or timezone
java.time.LocalDateTime
  • A date-time without a time-zone component in the ISO-8601 calendar. E.g. 2016-01-26T07:30:20.383
  • Does not store or represent a time-zone
java.time.LocalTime
  • A time without a time-zone in the ISO-8601 calendar system. E.g. 07:30:20.383
  • Does not store or represent a date or timezone
java.time.ZonedDateTime
  • offers date-time with a time-zone in the ISO-8601 calendar system e.g. 2007-12-03T10:15:30+01:00 Europe/Paris
  • Time-zone related aspects have been handled with a lot of care but we will delve into that in future posts

Internal representation of Java 8 time classes and joda-time

This means that getters for Java 8 have O(1) complexity due to its internal representation. joda-time as you can see stores millis from epoch and requires calculation to return parts of the date. Refer to this article for a performance comparison of Java 8 vs joda-time.

Additional Packages

java.time.chrono

Generic API for calendar systems other than the default ISO. Provides alternate calendars like
ISOChronology – ISO-8601 calendar or the default calendar used world wide which uses the Gregorian calendar
HijrahChronology – Islamic, Muslim or Hijri calendar is a lunar calendar used to determine proper dates for Islamic holidays and rituals. Hijrah is the year Muhammad and his followers migrated to Mecca. What is a good post if not filled with fun facts!!
JapaneseChronology – Japan uses Gregorian calendar with year designations stating the year of reign of the current emporer. E.g. “the 3rd year of Santosh” (if I happened to be a Japanese emporer in previous births) may map to 753 AD
MinguoChronology – Also known as Republic of China calendar. Better known as Taiwan and its territories (Yes, Mainland China is apparently called People’s Republic of China). 1912, year of founding of Republic of China is the first year and 2017 is “106th year of the republic”
ThaiBuddhistChronology – Primarily used in Thailand alongside the Thai solar calendar (Gregorian based). Is similar to Hijri calendar, to determine dates for traditional event and religious practices.

java.time.format

Provides classes to print and parse dates and times. DateTimeFormatter is the primary class for parsing and printing date-time objects. It provides predefined constants and patterns but if you want to use more complex formatters, DateTimeFormatBuilder is the class to use. We will follow up with a post to look at DateTime formatting in detail.

java.time.temporal

Access to date and time using fields and units, and date time adjusters. Allows for implementing plus/minus manipulations on date-time objects using Temporal fields (e.g. days, hours, months, etc)

java.time.zone

The package provides support for time-zones, their rules and the resulting gaps and overlaps in the local time-line typically caused by Daylight Saving Time. This warrants a dedicated post.

Conclusion

Java 8 Date Time API is not only well written but overcomes the obvious pitfalls of the previous API. With immutability and thread-safety along with fluent API design will make it very easy to incorporate it in very complex use cases. This post only scratches the surface of this package. Follow up posts with cover detailed examples, date-time formatting, time-zones and the extensible aspect of this API.