The Date and Time API (JSR 310) provides support for date, time and calendar related calculations. The reference implemation (RI) for this JSR is the ThreeTen Project . and was provided for inclusion into JDK 1.8. The Date and Time API is relative to the java.time
package and subpackages; java.time.chrono
, java.time.format
, java.time.temporal
and java.time.zone
.
JSR 310 achieved several design goals.
The Date and Time API uses the International Organization for Standardization date and time-related data exchange model (ISO 8601). The ISO 8601 standard is formally called, “Data elements and interchange formats – Information interchange – Representation of dates and times”. The standard is based on the Gregorian calendar. Regional calendars are also supported.
See Appendix A for more information on fluent APIs.
JSR 310 supercedes, but does not deprecate java.util.Calendar
, java.util.GregorianCalendar
, java.util.Date
, java.util.DateFormat
, java.util.TimeZone
and java.sql.Date
. JDK 8 provides methods to these classes to convert to and from the JSR 310 types for legacy support.
// Legacy -> New -> Legacy
Calendar
c
=
Calendar
.
getInstance
();
Instant
i
=
c
.
toInstant
();
Date
d
=
Date
.
from
(
i
);
// New -> Legacy -> New
ZonedDateTime
zdt
=
ZonedDateTime
.
parse
(
"2014-02-24T11:17:00+01:00"
+
"[Europe/Gibraltar]"
)
GregorianCalendar
gc
=
GregorianCalendar
.
from
(
zdt
);
LocalDateTime
ldt
=
gc
.
toZonedDateTime
().
toLocalDateTime
();
JSR 310 is flexible enough to allow for the addition of new calendars. When creating a new calendar, classes will need to be implemented against the Era
, Chronology
and ChronoLocalDate
intefaces.
Four regional calendars are packaged with the API.
With Regional calendars, you will not be using the main classes of the ISO Calendar.
The primary java.time
package of the API provides the ISO 8601 calendar system that is based on Gregorian rules. This and the related packages of the API provides a very easy to use interface into time as you can see in the example of determining age difference between presidents.
public
final
static
String
DISNEY_BIRTH_YEAR
=
"1901"
;
public
final
static
String
TEMPLE_BIRTH_YEAR
=
"1928"
;
...
Year
birthYear1
=
Year
.
parse
(
DISNEY_BIRTH_YEAR
);
Year
birthYear2
=
Year
.
parse
(
TEMPLE_BIRTH_YEAR
);
long
diff
=
ChronoUnit
.
YEARS
.
between
(
birthYear1
,
birthYear2
);
System
.
out
.
println
(
"There is an age difference of "
+
Math
.
abs
(
diff
)
+
" years."
);
$
There
is
an
age
difference
of
27
years
.
The primary classes of the API are presented here with key text derived from the online API to guide you in the selection for their use. The sections that follow highlight key attributes and usage of some of these classes.
Instant
LocalDate
LocalTime
LocalDateTime
OffsetTime
OffsetDateTime
ZonedDateTime
ZoneOffset
ZonedId
Year
YearMonth
MonthDay
DayOfWeek
Month
Duration
Period
Clock
JSR 310 uses the UNIX Epoch for it’s default ISO 8301 calendar with zero starting at 1970-01-01T00:00Z. Time is continuous since then, with negative values for instances before it.
To get an instance of the current time, simply call the Instant.now()
method.
Instant
i
=
Instant
.
now
();
System
.
out
.
println
(
"Machine: "
+
i
.
toEpochMilli
());
$
Machine:
1392859358793
System
.
out
.
println
(
"Human: "
+
i
);
$
Human:
2014
-
02
-
20
T01:
20
:
41.402
Z
The Clock
class provides access to the current instant, date and time while using a time-zone.
Clock
clock1
=
Clock
.
systemUTC
();
Instant
i1
=
Instant
.
now
(
clock1
);
ZoneId
zid
=
ZoneId
.
of
(
"Europe/Vienna"
);
Clock
clock2
=
Clock
.
system
(
zid
);
Instant
i2
=
Instant
.
now
(
clock2
);
The Date-Time API uses the Time-Zone Database (TZDB).
A Duration
is a time-based amount consisting of days, hours, minutes, seconds and nanoseconds. A duration is the time between two instances on a time line.
The usage for a duration as a parsable string is "PnDTnHnMnS"
where P stands for period and T stands for time. D, H, M and S are days, hours, minutes and seconds prefaced by their values.
Duration
d1
=
Duration
.
parse
(
"P2DT3H4M1.1S"
);
Durations may also be created by using the of[Type]
method and may also have hours, minutes, seconds and nonoseconds added or substracted to their associated states.
Duration
d2
=
Duration
.
of
(
41
,
ChronoUnit
.
YEARS
);
Duration
d3
=
Duration
.
ofDays
(
8
);
d3
=
d3
.
plusHours
(
3
);
d3
=
d3
.
plusMinutes
(
30
);
d3
=
d3
.
plusSeconds
(
55
).
minusNanos
(
300
);
The Duration.between()
method can be used to create a Duration
from a start and end time.
Instant
birth
=
Instant
.
parse
(
"1967-09-15T10:30:00Z"
);
Instant
current
=
Instant
.
now
();
Duration
d4
=
Duration
.
between
(
birth
,
current
);
System
.
out
.
(
"Days alive: "
+
d4
.
toDays
());
A Period
is a date-based amount consisting of years, mounths and days.
The usage for a period as a parsable string is "PnYnMnD"
where P stands for period, Y, M and D are days, years, months and days prefaced by their values.
Period
p1
=
Period
.
parse
(
"P10Y5M2D"
);
Periods may also be created by using the of[Type]
method and may also haveyears months and days added or substracted to their associated states.
Period
p2
=
Period
.
of
(
5
,
10
,
40
);
p2
=
p2
.
plusYears
(
100
);
p2
=
p2
.
plusMonths
(
5
).
minusDays
(
30
);
Interoperation between the java.time
and java.sql
types has been achieved. Table 18-1 provides a visual mapping of the JSR 310 types to the SQL as well as XML Schema (XSD) types.
The DateTimeFormatter
class provides a formatting capability for printing and parsing date-time objects. The upcomgin example demonstrates the use of pattern letters with the ofPattern()
method of the class. Usable pattern letters are identified in the JavaDoc for the DateTimeFormatter
class,
LocalDateTime
input
=
LocalDateTime
.
now
();
DateTimeFormatter
format
=
DateTimeFormatter
.
ofPattern
(
"yyyyMMddhhmmss"
);
String
date
=
input
.
format
(
format
);
String
logFile
=
"simple-log-"
+
date
+
".txt"
;
Table 18-2 contains examples of using predefined formatters using the following structure:
System
.
out
.
(
LocalDateTime
.
now
()
.
format
(
DateTimeFormatter
.
BASIC_ISO_DATE
));
Class | Formatter | Example |
| BASIC_ISO_DATE | 20140215 |
| ISO_LOCAL_DATE | 2014-02-15 |
| ISO_OFFSET_DATE | 2014-02-15-05:00 |
| ISO_DATE | 2014-02-15 |
| ISO_DATE | 2014-02-15-05:00 |
| ISO_LOCAL_TIME | 23:39:07.884 |
| ISO_OFFSET_TIME | 23:39:07.888-05:00 |
| ISO_TIME | 23:39:07.888 |
| ISO_TIME | 23:39:07.888-05:00 |
| ISO_LOCAL_DATE_TIME | 2014-02-15T23:39:07.888 |
| ISO_OFFSET_DATE_TIME | 2014-02-15T23:39:07.888-05:00 |
| ISO_ZONED_DATE_TIME | 2014-02-15T23:39:07.89-05:00 [America/New_York] |
| ISO_DATE_TIME | 2014-02-15T23:39:07.891 |
| ISO_DATE_TIME | 2014-02-15T23:39:07.891-05:00 [America/New_York] |
| ISO_ORDINAL_DATE | 2014-046 |
| ISO_WEEK_DATE | 2014-W07-6 |
| RFC_1123_DATE_TIME | Sat, 15 Feb 2014 23:39:07 -0500 |