Featured in
Architecture & Design

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Process & Practices

In-App Subscriptions Made Easy

There are various types of subscriptions: recurring, non-recurring, free-trial periods, various billing cycles and any possible billing variation one can imagine. But with lack of information online, you might discover that mobile subscriptions behave differently from what you expected. This article will make your life somewhat easier when addressing an in-app subscriptions implementation.

Featured in
Operations & Infrastructure

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Enterprise Architecture

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Java Time API Now In Java 8

ThreeTen, the reference implementation of JSR 310 Date and Time API, is now included in JDK 8 Early Access b75. The Java Time API for JDK 8 is under the package java.time, moving away from the javax.time package of earlier implementations. The Java Time Javadoc draft is also available.

All the Java Time classes are immutable and thread-safe. They are based on the ISO 8601 calendar system, the de facto world calendar following the proleptic Gregorian rules. Support for other calendar systems are provided in the java.time.calendar and java.time.temporal packages. Besides classes for dates and times, the API also has classes for clocks, periods and durations, and enums for month and day-of-week.

There are a lot of classes in the Java Time API, but most applications can start with these date/time types.

Instant

A numeric timestamp, stored with nanosecond resolution. Useful for capturing a point in time, similar to System.currentTimeMillis(). Instant is the closest equivalent class to java.util.Date. The instant when printed looks like '2000-12-01T12:30:00.000Z'.

LocalDate

A date without a time, offset or time zone. Useful for storing a birthday for example. The date when printed looks like '2000-12-01'

LocalTime

A time without a date, offset or time zone. Useful for storing store hours for example. The time when printed looks like '12:30:00.000'.

LocalDateTime

A date and time without the offset or time zone. The date and time when printed looks like '2000-12-01T12:30:00.000'.

ZonedDateTime

A date and time with offset and time zone. Useful for performing calculations that takes into account the time zone like 'America/New_York'. ZonedDateTime is the closest equivalent class to java.util.GregorianCalendar. The date and time when printed looks like '2000-12-01T12:30:00.000-05:00[America/New_York]'

It is recommended whenever possible, to use a simpler classes without a time zone to model the domain, like LocalDate, LocalTime and LocalDateTime. The widespread use of time zones tends to add considerable complexity to an application. Many applications can use the simpler classes, with the time zone added only at the user interface layer.

Other notable classes in the Java Time API are:

Clock

A clock providing access to the current instant, date and time using a time zone. A clock can be used instead of System.currentTimeMillis() and TimeZone.getDefault(). Although all key date and time classes have a now() factory method that uses the system clock, the primary purpose of this abstraction is to allow alternate clocks to be injected, which can greatly simplify testing.

Duration

A duration between two instants on the time-line, stored with nanosecond resolution. This class models a duration of time and is not tied to any instant. The model is directed, meaning that the duration can be negative. The duration when printed looks like 'PT3600S'.

Period

A period of time expressed in units meaningful to humans, such as '1 Year, 2 Months and 3 Days'. The model is directed, meaning that individual parts of the period may be negative. The period when printed looks like 'P1Y2M3D'.

ZoneId

A time zone ID, such as America/New_York.

ZoneOffset

A time zone offset from Greenwich/UTC, such as +02:00.

The java.time.zone 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. There is also the java.time.format package for printing and parsing date-time objects, although in most cases, the date and time classes' toString() and parse() methods should be sufficient. The java.time.temporal package provides access to date and time using fields and units, additional value type classes for the most important sub-parts of a date, and base support for calendar systems other than the default ISO. This package provides additional functionality for more advanced use cases.

Users who wish to try the new JDK 8 Time API can download JDK 8 b75, using the Javadoc as a guide. Users who would like to use an IDE with JDK 8 support can use the latest IntelliJ IDEA or Netbeans IDEs. Those looking for third party tutorials should make sure they are looking at recent articles as the API have had a lot of changes in the past few years. Also note that changes to the Java Time API classes and methods are expected to continue until JDK 8 is released. Developers interested in knowing all the features coming in JDK 8 and when they actually get included can review the JDK feature list and changesets.

InfoQ has covered the announcement of JSR 310 back in early 2007, when the JSR was originally planned to be shipped with JDK 7. InfoQ has also interviewed Stephen Colebourne, lead of the JSR 310, back in 2010, during the first of the JSR's early draft reviews. The last InfoQ coverage of JSR 310 was on September 2012, when the JSR was officially added to the Java 8 feature list.

Unfortunately not only has it dragged along for ages, there are 3(!) competing APIs and packages around Date and Time in Java 8, none of them really compatible with the other, aside from possible factories for the new java.time (JSR 310) classes based on java.util.Date and Calendar.

The class Duration is declared 3 times!One case an abstract base class in javax.xml.datatype, probably the only case that's been there before and not directly related.Then there's the final Duration class in java.time, defined by JSR 310, plus Java 8 as we know, also get first class JavaFX support. Where we have yet another Duration class, in javafx.util. This immutable but not final(!) class has a totally different design and naming scheme than JSR 310, more along the lines of BigDecimal at leasts when it comes to date and time arithmetics, similar to other JavaFX operations e.g. for Binding.All of JavaFX is heavily dependent on the Duration class, it's used in all time-sensitive operations like animation, timeline(!), etc.It is nearly impossible, that JavaFX Duration and the "odd fellow" from JSR 310 are going to be compliant or merged any time soon. Too different in design and approach, not to mention, that the JavaFX one can be extended and users of JavaFX may do so already, another area where the two are incompatible.

A shamble making Java more complex, not to mention, that the java.time package alone is somewhere over 1MB, making it a no-go for any of the smaller Java SE 8 Profiles.

More than 6 (SIX) years, (first JSR Review Ballot ended on Feb/12/2007) to implement an essential API, and not starting from zero, but from an already well designed, complete and popular implementation (Jodatime).

It is recommended whenever possible, to use a simpler classes without a time zone to model the domain, like LocalDate, LocalTime and LocalDateTime. The widespread use of time zones tends to add considerable complexity to an application. Many applications can use the simpler classes, with the time zone added only at the user interface layer.

First of all, the opposite of this particular phrase is true. Lacking a consistent model for time zones within time representation in applications does add considerable complexity. However, accounting of the time zone information throughout an application simplifies things a lot.

The reason is that whatever Gregorian time representation you choose (which seems to be the case with the described API), it automatically HAS a time zone attached, usually the system's local timezone. Any connection of your application to an external system (like having a database on another computer, calling a web service, formatting a HTML page etc.) may encounter a different regional setting. If the other party followed your recommendation, you encounter chaos.

For instance, take the LocalDate in your example, 2000-12-01, which is printed out the same way (similar to ISO8601, but disregarding time zone). An ISO8601 parser would parse it in the UTC time zone, even if the developer intended it in another local time zone.

Also, mobility makes apps cross timezone boundaries when users travel. Does LocalDate compensate when someone changes the system timezone? How does it do that, if it does not store the initial time zone when it was created?

If you are storing someone's birthday, you should use a LocalDate. That is because a birthday has no relationship to a time-zone, its the day that matters, not the zone. This even applies if sending a birthday across the network to another machine/service - you just send the date, not the zone.

Your suggestion to rely on the system time-zone is also flawed. Server-side applications, such as websites or web-services, will be called by users in many time-zones. Relying on the system time-zone will frequently give the wrong result.

What is important is to pass a known *instant* to another system, something that can be done using the OffsetDateTime class that is explicitly designed for interaction with the network and database. That class contains an offset from UTC/Greenwich, not a time-zone. The two are distinct and different, and learning that difference will definitely aid in understanding the API, and what each class is for.

Building an API for the JDK is entirely different to building an API in your day job, or in an open source project. Thats because it can never be changed once included in a JDK release. Thus, the design has to be refined and tweaked with every variant considered to ensure that what is included in the JDK will stand the test of time.

While different contexts may apply different meanings to a "birthday", a "day" - any day - is not time-zone independent (as reflected by org.joda.time.LocalDate). For instance, filtering by "day" without accounting for time zone may yield results that happened "yesterday" or "tomorrow" in a different time zone. Only the context can determine if this is desired or not.

It is not my suggestion to rely on the system time-zone (a.k.a. the "local" time).

Ideally everybody is up-to-date with calendars and time zones, but this is not true. My criticism is about the suggestion to continue to not be aware of these issues because they would increase the complexity of the application. It is our current time system that already presents this complexity, and being unaware of it leads to problems (usually at a later time, when the codebase is already filled with timezone-unaware calculus and hacks).

Building an API for the JDK is entirely different to building an API in your day job, or in an open source project. Thats because it can never be changed once included in a JDK release. Thus, the design has to be refined and tweaked with every variant considered to ensure that what is included in the JDK will stand the test of time.

If that's the case, then explain the previous attempts at implementing a time API. I could go on...