This Javadoc is for an alpha release of the ThreeTen project.


java.util Amended OpenJDK classes that integrate JSR-310 with the existing date and time APIs.
javax.time Provides classes to manage the continuous time-scale including a wrapper for the system clock.
javax.time.calendar Provides classes to manage the human time-scale including date, time, date-time and time-zone representations.
javax.time.calendar.format Provides classes to print and parse dates and times. Provides classes to implement time-zones and their rules.
javax.time.i18n Provides classes representing dates and times in alternate calendar systems.


This Javadoc is for an alpha release of the ThreeTen project. The JSR-310 specification will be derived over time from the ThreeTen project. Since the ThreeTen project is incomplete, the JSR-310 specification is also incomplete.

ThreeTen defines a new Date and Time API for Java. This is a relatively large API, but each class follows a common design language, especially in method prefixes. Once the prefixes are understood, the API is relatively simple to comprehend.

The key task is to choose the correct class for your needs. There is a high-level and a low-level API - this guide will focus on the high-level. Simply follow this guide to choose the best class:

  1. Do you want to store an essentially numeric timestamp? Then use Instant. This is useful for logging and persistence of a point in time and has in the past been associated with storing the result from System.currentTimeMillis().
  2. Do you want to store a date and time with a time-zone? Then use ZonedDateTime. This is useful if you want to perform accurate calculations of dates and times taking into account the time-zone, such as 'Europe/Paris'.
  3. Do you want to store the offset from UTC? The offset is of the form '+01:00'. This is frequently found in XML messages and other forms of persistence, but contains less information than a full time-zone.
    1. With the offset, do you want to store a date without a time? Then use OffsetDate. This stores a date like '2010-12-03+01:00'.
    2. With the offset, do you want to store a time without a date? Then use OffsetTime. This stores a date like '11:30+01:00'.
    3. With the offset, do you want to store a date and time? Then use OffsetDateTime. This stores a date like '2010-12-03T11:30+01:00'.
  4. Do you want to store a date without a time? Then use LocalDate. This stores a date like '2010-12-03' and could be used to store a birthday.
  5. Do you want to store a time without a date? Then use LocalTime. This stores a date like '11:30' and could be used to store an opening or closing time.
  6. Do you want to store a date and time? Then use LocalDateTime. This stores a date like '2010-12-03T11:30'.
  7. Do you want to store a year and month without a day or time? Then use YearMonth. This stores a year and month, such as '2010-12' and could be used for a credit card expiry.
  8. Do you want to store a month and day without a year or time? Then use MonthDay. This stores a month and day-of-month, such as '--12-03' and could be used to store an annual event like a birthday without storing the year.
  9. Do you want to store a year on its own? Then use Year. This stores a single year in isolation, such as '2010'.
  10. Do you want to store a month on its own? Then use MonthOfYear. This stores a single month-of-year in isolation, such as 'DECEMBER'.
  11. Do you want to store a day-of-week on its own? Then use DayOfWeek. This stores a single day-of-week in isolation, such as 'TUESDAY'.

All these classes are always valid, immutable and thread-safe. They are all based on the ISO calendar system with a fixed 86400 second day. This is the de facto world calendar following the proleptic Gregorian rules. The i18n package contains other calendar systems.

The time-zone support is extensive. Information may be provided by multiple vendors, each of which may produce multiple versions of their data. The information may be updated while the system is running. Any update will not invalidate objects that have already been created.

Support is provided for printing and parsing all manner of dates and times. This support can be accessed via constants, a pattern or a builder.

The set of supported date-time fields can be extended by applications using the low-level API. This allows a new field, such as hour-of-fortnight to be created if desired.

Where the 86400 second day definition is insufficient, classes are provided to cover the UTC (with leap-seconds) and TAI time-scales. It is expected that most applications will be content with ignoring leap-seconds.

Beyond dates and times, the API also allows the storage of period and durations of time. A duration is a simple measure of time along the time-line in nanoseconds. A period expressed an amount of time in units meaningful to humans, such as years or hours. The Duration class is used to store a duration, while the Period class is the key class for storing a period.

Design notes

The API has two layers - the high-level API for use by applications, and the low-level API for use by frameworks. This separation proved to be the best way to handle complexity. Where possible, applications should stick with using the high-level API.

The high-level API avoids the use of null. Methods throw NullPointerException on input and do not return null. However, check methods starting with 'is' will normally tolerate null input. The low-level API makes frequent use of null return values as an indication of not found, or similar meaning.

The API is designed to be type-safe where reasonable in the main high-level API. Thus, there are separate classes for the distinct concepts of date, time and date-time, plus variants for offset and time-zones. The core 7 date-time classes, plus Instant, handle the needs of most applications. Further classes handle other combinations - year, year-month and month-day in a type-safe manner.

In a language like Java, the use of many different types tends to cause API bloat. This is handled here through the use of common method naming patterns throughout the API. The common prefixes are 'of', 'get', 'is', 'with', 'plus', 'minus', 'to' and 'at'. See LocalDate for an example of each of these methods.

Following type-safety to its logical conclusion would result in more classes, especially for time - hour-minute, hour-minute-second and hour-minute-second-nanosecond. While logically pure, this was not possible in practice, as the additional classes would have excessively complicated the API. Notably, there would be additional combinations at the offset and date-time levels, such as offset-date-hour-minute. To avoid this explosion of types, LocalTime is used for all precisions of time. By contrast, some additional classes were used for dates, such as YearMonth. This proved necessary, as the API for year-month is significantly different to that for a date.

Similarly, type-safety would require a separate class for each field in date-time. This would have created a class for hour-of-day, minute-of-hour, day-of-year, and many more. This approach was tried, but was excessively complicated in the Java language, lacking usability. Therefore two classes, DateTimeField and DateTimeFields handle the full range of fields without dedicated types.

A similar problem occurs with periods. There is a case for a separate class for each period unit, such as a type for years and a type for minutes. However, this yields a lot of classes and a problem of type conversion. As such, a standard set of fields was chosen for Period, with PeriodField and PeriodFields handling the more unusual cases.

Multiple calendar systems is an awkward addition to the design challenges. The approach taken is to keep calendar systems out of the main classes to limit complexity. This is based on the principal that most users want the standard ISO calendar system. In addition, those wanting a historically accurate Gregorian-Julian calendar system need to think carefully about the cutover date between the two systems, which varied by location.

A further design limitation was the desire to allow date-time fields to be defined by applications that would be integrated into those defined by the core. The DateTimeField approach achieves this, but at the cost of some complexity.

Implementation notes

All API methods should document whether they accept null or not. If a method does not accept null, and null is passed in, then a NullPointerException will be thrown. The NullPointerException is not explicitly documented in each method.