JSR-310 Date and Time API
Public Review – Version 0.8
Many Java applications require logic to store and manipulate dates and times. At present, Java SE provides a number of disparate APIs for this purpose, including Date, Calendar, SQL Date/Time/Timestamp and XML Duration/XMLGregorianCalendar. JSR improves on these APIs and covers many additional use cases needed by developers.
As an example, Java developers currently have no standard Java SE class to represent the concept of a date without a time, a time without a date or a duration. The result of these missing features has been widespread abuse of the facilities which are provided, such as using the Date or Calendar class with the time set to midnight to represent a date without a time. Such an approach is very error-prone - there are certain time zones where midnight does not exist once a year due to the daylight saving time cutover!
JSR-310 tackles this by providing a comprehensive set of date and time classes suitable for Java SE today. The API includes:
Date and Time
Date without Time
Time without Date
Offset from UTC
Formatting and Parsing
A selection of calendar systems
This document is an introduction to the full API, which consists of the Javadoc. The Javadoc specification is available via the JCP JSR 310 Date and Time API . The early access reference implementation included in JDK 8 is available for download. Additional information related to JSR 310 can be found at the Threeten Project on GitHub.
This draft guide is released to gain feedback. Since it is a draft, readers are advised to take care when referencing it.
The domain of dates, times and other temporal concepts is large and complex - much more complex than is often apparent. A key aim of the JSR is to allow the API to explain this complexity simply by the way that the features are exposed. In this way, the user of the API is guided to make the correct choice, minimising the potential for bugs.
Part of this process is determining and using a consistent terminology. For this purpose, JSR-310 is building upon the excellent work of the ISO-8601 standard. However, we have changed a few terms, thus the entire terminology is defined here for clarity:
The single line or axis of time from the past to the future.
A single instantaneous point on the time line.
A quantity of time equal to the directed difference between any two instants on the time line.
A known, well-defined, instant that can be used as a reference point to measure other instants from.
A system of assigning meaningful values to instants in relation to a known epoch.
A time-scale fundamentally based on a single incrementing number. This is usually defined as a duration relative to an epoch.
International Atomic Time (TAI)
The primary continuous time-scale intended for scientific and technical purposes, defined by international standard. It is agreed internationally based on atomic clocks and is completely continuous. All days have exactly 86400 seconds. The time-scale is measured in terms of the SI second unit.
Coordinated Universal Time (UTC)
The standard time-scale intended for civil purposes, defined by international standard. It follows TAI except for the insertion or removal of an integral number of leap seconds which are intended to keep UTC closer to the real and variable length of a solar day. Most days have 86400 seconds, but some have 86399 or 86401 seconds. The time-scale is measured in terms of the SI second unit.
A time-scale that is not defined by international standard, but is widely implemented by computer systems. This time-scale treats all days as having exactly 86400 seconds while staying in tune with UTC. This definition is, of course, not actually possible, however it is a suitable approximation for most normal computing use cases.
The time-scale is typically implemented by relying on the fact that clocks in most computers are not accurate and the functions that tell the time are loosely specified. One approach is to slow time down around a leap second, a second is to make time go back one second, while another is to make the system hang for a second.
Coordinated Universal Time with Smoothed Leap Seconds (UTC-SLS)
An internet draft that defines a way to map UTC (with leap seconds) to simplified "UTC" (without leap seconds). The approach smooths leap seconds over the last 1000 seconds of the day. This provides an exact mapping between a highly accurate clock and the form of time that is useful to computer programmers. This approach, like any that changes the meaning of the second, is referred to as rubber seconds.
A second that is slightly longer (or shorter) than the SI unit of a second. This can be used to hide the existence of a leap second.
JSR 310 time-scale
A simple time-scale designed to provide the time-of-day to an accuracy suitable for most Java applications. The Java Time scale is described fully in java.time.Instant, summarized here as:
midday will always be exactly as defined by the agreed international civil time
other times during the day will be broadly in line with agreed international civil time
the day will be divided into exactly 86400 subdivisions, referred to as "seconds"
the Java "second" may differ from an SI second
The UTC-SLS draft standard is one way to implement the JSR-310 time-scale if the application has access to an accurate underlying clock.
A way of defining time that is meaningful to humans and used in everyday life, also known as a calendar system. It uses individual fields, such as year, month, day, hour minute and second. There are many chronologies, each defining fields in different ways.
A quantity of time, expressed in terms of the fields of a particular calendar system, such as "five years."
A period, usually between +14 and -12 hours, that a given location differs from UTC at any given instant. The offset used for a particular location is controlled by government. The value used originally aimed to ensure that the calendar system time of midday (12:00) was equivalent to the solar midday. Today, the offset is influenced by many other factors.
Daylight Saving Time (DST)
A change to the zone offset that typically occurs each summer. The standard approach is to move clocks forward in the Spring and back in the Autumn/Fall. The two periods are generally known as Summer and Winter time. Whether a given location does this, and on what dates is controlled by local authorities.
Gap and Overlap
A gap occurs in the local time-line when clocks move forwards, typically in Spring due to DST. An overlap occurs in the local time-line when clocks move back, typically in Autumn/Fall due to DST.
An area of the planet that uses the same zone offset and observes the same rules for changing it due to daylight savings time. A time zone is controlled by government. Some countries have multiple time zones, others share a time zone with their neighbours.
Time zone rules
A set of rules, for each time zone, that determine how the zone offset varies. A simple set of rules consist solely of a fixed, year round, offset. More complex rules include annual daylight savings changes, historical data and predicted future changes. There are multiple sources of time zone rule data.
A date or time defined solely using calendar system fields. A local date or time does not represent a fixed instant, or range of instants. For example the local date of 3rd December 2009 will start at one instant in Australia, a later instant in the UK, and an even later instant in the USA. In all cases however, the same local date is referred to.
A date or time defined using calendar system fields and a zone offset. Unlike a local date or time, an offset date or time can be converted to and from an instant. For example the local date of 3rd December 2009 refers to a specific instant once the zone offset of 1 hour ahead of UTC is specified.
A date-time defined using calendar system fields, zone offset and time zone. As with an offset date or time, a zoned date-time can be converted to and from an instant. In addition, the presence of a time zone allows accurate calculations of related date-times, such as adding 6 months (which may cause the zone offset to alter).
The JSR-310 classes should be immutable wherever possible. Experience over time has shown that APIs at this level should consist of simple immutable objects. These are simple to use, can be easily shared, are inherently thread-safe, friendly to the garbage collector and tend to have fewer bugs due to the limited state-space.
The API strives to be fluent within the standard patterns of Java SE. A fluent API has methods that are easy to read and understand, specifically when chained together. The key goal here is to simplify the use and enhance the readability of the API.
Clear, explicit and expected
Each method in the API should be well-defined and clear in what it does. This is not just a question of good Javadoc, but also of ensuring that the method can be called in isolation successfully and meaningfully.
The API should be extensible in well defined ways by application developers, not just JSR authors. The reasoning is simple - there are just far too many weird and wonderful ways to manipulate time. A JSR cannot capture all of them, but an extensible JSR design can allow for them to be added as required by application developers or open source projects.
We classify dates and times into two basic use cases - machine-scale and human-scale.
Machine-scale time represents the passage of time using a single, continually incrementing number. The rules that determine how the scale is measured and communicated are typically defined by international scientific standards organizations.
Two key classes are defined to represent machine-scale time:
Instant - An instant on the time-line
Duration - A duration of time
These classes use nanosecond precision. The classes have sufficient accuracy to represent any nanosecond instant within the current age of the universe. The epoch used is 1970-01-01T00:00:00Z (midnight at the start of 1 January 1970 UTC), as per the current Java SE date and time classes.
Human-scale time represents the passage of time using a number of named fields, such as year, month, day, hour, minute and second. The rules that determine how the fields work together are defined in a calendar system.
The design adopted splits the classes into value types and fields/units. Simple applications will not need to be concerned with fields and units.
The high level API contains the following key classes:
LocalDate - A date, with no time nor zone-offset
LocalTime - A time, with no date nor zone-offset
LocalDateTime - A date-time, with no zone-offset
OffsetTime - A time and zone-offset, with no date
OffsetDateTime - A date-time and zone-offset
ZonedDateTime - A date-time, zone-offset and time-zone
ZoneOffset - An offset from the time in UTC/GMT
ZoneId - A time-zone identifier, used to find the underlying rules
Each of these date-time classes represent time in the ISO calendar system, defined by ISO-8601. This is also known as the proleptic Gregorian calendar system, and is the de facto civil calendar system used today in the vast majority of the world.
Each date-time field can be represented as a value, which is expressed as a long. Some fields also have an enum defined for code clarity and safety. These include month, day of week, am/pm and quarter.
Although there are lots of classes and each class has lots of methods, the "conceptual weight" of the API is greatly reduced through consistent use of method name prefixes. Some of these prefixes differ from JavaBean conventions because the classes are immutable:
get - Gets the specified value
with - Returns a copy of the object with the specified value changed
plus/minus - Returns a copy of the object with the specified value added/subtracted
multipliedBy/dividedBy/negated - Returns a copy of the object with the specified value multiplied/divided/negated
to - Converts the object to another related type
at - Returns a new object consisting of this date-time at the specified argument, acting as the builder pattern
of - Factory methods that don't involve data conversion
from - Factory methods that do involve data conversion
Applications will also commonly use the TemporalAdjuster interface and the standard implementations provided in TemporalAdjusters. These pre-packaged common manipulation functions like “next Wednesday” or the “last day of the month”. They are especially valuable in capturing the intent of business logic.
Dates and times are formed from fields and units.
A unit is a measurable unit of time, such as a year, month or hour. The set of known units can be extended by applications.
A field is used to express part of a larger date-time, such as year, month-of-year or second-of-minute. The set of known fields can also be extended by applications.
Fields and units work together with the abstractions Temporal and TemporalAccessor provide access to date-time classes in a generic manner.
Other calendar systems are supported with a separate calendar-neutral API. This is focused on the Chronology and ChronoLocalDate classes. These do not have the same breadth or depth as the main ISO calendar system API.
It is recommended that applications use the classes in the main API for all communication between systems and subsystems, including public APIs, storage to a database and communication across the network. The calendar neutral API should be used primarily for user localization.
The division in the API between machine-scale and human-scale is deliberate and necessary, as the two time-scales represent different ways of looking at time.
The machine-scale approach is very time-line focused. For example, Instant simply represents an instant on the time-line. The only meaningful operations on the class are to check whether the instant is before or after another instant. These classes will be of most use for recording event timestamps and logging.
The human-scale approach is very focused on what the time means to a human, through the use of the fields. In addition to getting and setting the field values, methods are provided to perform mathematical operations, such as adding three days to a date. These classes will be of most use in business logic, such as representing the departure time of a train or a customer's birthday.
The design adopted is notably different to the Java SE Calendar API and the Joda-Time API.
The Java SE Calendar API has a single base class that represents both the date-time and the calendar system. Different calendar systems are implemented as subclasses. This design is flawed as calendar systems are too different to be properly treated as subclasses.
The Joda-Time API has simple date-time classes with a plug-in calendar system (chronology). This design, while better than Calendar, is also flawed because each method on the API is unable to properly define its result. For example, the getMonthOfYear() method normally returns a value from 1 to 12, however if the Coptic calendar system has been "plugged in" then the method will return results from 1 to 13.
The JSR-310 design ensures that each method on the core API is able to fully define its input and output by focusing the entire class on a single calendar system. Instead, users with advanced requirements have to study the API a little more closely and use the low-level temporal classes.
The ThreeTen project and JSR-310 needs feedback! We need reviewers to read the guide and Javadoc, and where possible, try out the code (in the JDK 8 Early Access Releases).
Specifically, we need to know if
whether there are key use cases that are missing (or you can't find)
specific method names are unclear
the API is clear, unclear or about right
anything else that is an issue
Feedback and comments on the Public Review draft should be sent to email@example.com.
Feedback is public information on a trust and respect basis for the public good and may be used by anyone in any way forever.