Among the most anticipated additions to the Java platform coming in Java 8 is JSR 310: The Date and Time API. Find out how the Java Date and Time API addresses the need for a more robust date and time infrastructure in Java SE, then familiarize yourself with the
java.timeclasses you're most likely to use, in this inaugural installment of Java 101: The next generation.
Articles in the original Java 101 series are among the most frequently sought archives on JavaWorld. Published from 2000 to 2004, the series was launched with Jacob Weintraub's "Learn Java from the ground up." My subsequent 30 installments addressed a wide range of Java programming topics, including object-oriented language basics, threaded programming, and garbage collection in Java. (Visit the Java 101 series archive for a listing.)
Naturally, the Java platform has evolved significantly since those days. JDK 5, released in September 2004, was a game-changer for many Java developers, and some believe that Java 8 will be just as significant. Both releases feature important additions to the Java language, as well as APIs that address the emergent needs (then and now) of Java programming. Java 101: The next generation will guide you through some of the newer Java language syntax, APIs, and libraries that are most relevant to Java developers today, starting with one of the most anticipated additions to Java SE 8: the Java Date and Time API.
I'll start with an overview of the Date and Time API, explaining why it's such an important addition to Java SE. Then we'll tour the three fundamental Date and Time API type categories, which are found in the
- Instant and Duration
- LocalDate, LocalTime, and LocalDateTime
- ZoneId, ZoneOffset, ZonedDateTime, and OffsetDateTime
Introducing the Java Date and Time API
Date and Time is a new date, time, and calendar API for the Java SE platform. It was developed under JSR 310 and replaces Java's existing date and time infrastructure based on
java.util.Calendar. You should use this API in any application that would otherwise use the legacy
TimeZone subclasses such as
java.util.GregorianCalendar; or associated classes such as
The Date and Time API distinguishes between machine and human views of a timeline, which is an always increasing sequence of instants, or points along the timeline. The machine view reveals a sequence of integral values relative to the epoch (e.g., midnight, January 1, 1970), with positive values identifying instants after the epoch and negative values identifying instants before the epoch. The human view reveals a set of fields (e.g., year, month, day-of-month, hour, minute, and second).
Why do we need a new Date and Time API?
Java 1.0 introduced
System.currentTimeMillis(), which could return a machine view of the timeline with millisecond precision. It also introduced the
java.util.Date class, which returned a human view. It soon became evident that there were several flaws with this class:
- Constructors that accept year arguments require offsets from 1900, which has been a source of bugs.
- January is represented by 0 instead of 1, also a source of bugs.
Datedoesn't describe a date but describes a date-time combination.
Date's mutability makes it unsafe to use in multithreaded scenarios without external synchronization.
Dateisn't amenable to internationalization.
In an attempt to fix these flaws, Sun introduced
java.util.Calendar and related classes with the Java 1.1 release. Unfortunately,
Calendar was also riddled with flaws, including the following:
- It isn't possible to format a calendar.
- January is represented by 0 instead of 1, a source of bugs.
Calendarisn't type-safe; for example, you must pass an
int-based constant to the
get(int field)method. (In fairness, enums weren't available when
Calendar's mutability makes it unsafe to use in multithreaded scenarios without external synchronization. (The companion
java.text.DateFormatclasses share this problem.)
Calendarstores its state internally in two different ways -- as a millisecond offset from the epoch and as a set of fields -- resulting in many bugs and performance issues.
Timestamp classes extend
java.util.Date and inherit its problems. Also, in order to prevent setting the time part in the
Date class and the date part in the
Time force various setter methods to throw
IllegalArgumentException, which is messy.
Clearly, a more robust API was needed in order to address date and time functionality in Java programs.