A new new infrastructure for time and date handling.
Actually, it's not all that new, it's an evolution of the popular Joda-Time library, accepted into the JDK as JSR-310. Stephen Colebourne, who wrote Joda-Time, is the principal for the JSR.
Terms like "date" and "time" are overloaded, so one aim is to clearly define what terms mean (rule 3).
By these terms, a java.util.Date is not a date at all.
It's not going away. And if you're not using Java8 or planning to upgrade, you can and probably should go on using it.
However, it's interesting to look at the differences, they can demonstrate perceived deficiencies.
Sometimes they point to changed perceptions in common practices. For example, all java.time value objects are immutable; Joda-Time has mutable versions.
DateTime is gone
An instant is a point on the timeline, independent of any chronology
A date and time can be used to find an instant- if you have enough context, you can interconvert.
A date, time and zone offset
Joda-Time has Instant, but have you ever used it? DateTime implements ReadableInstant, so basically does everything an Instant does anyway.
// When is this exactly?
new org.joda.time.DateTime(2015, JANUARY, 14, 2, 3, 4).toMillis()
An instant is the "millis since epoch" (although now to nanosecond precision)
// Provide all the information
java.time.LocalDateTime.of(2015, JANUARY, 14, 2, 3, 4)
.toInstant(ZoneOffset.UTC)
// equivalent:
java.time.OffsetDateTime.of(java.time.LocalDate.of(2015, JANUARY, 14),
java.time.LocalTime.of(2, 3, 4),
ZoneOffset.UTC)
.toInstant()
OffsetDateTime or ZonedDateTime essentially replace DateTime
Instant replaces using a long (please...)
"Everyone knows" there are 12 months in a year etc., right?
That's not actually always the case. Other chronologies work differently. In java.time, classes like LocalDateTime are definitely using ISO chronology, though. In Joda-Time, theoretically not...
((org.joda.time.DateTime) datetime).getMonthOfYear() == 13;
// it can happen
((java.time.LocalDateTime) datetime).getMonthValue() == 13;
// never happens
((java.time.LocalDateTime) datetime).getMonth() == Month.DECEMBER;
// now months can be an enum
Help to make working with date/time objects understandable
Period is a date-based amount (4 days, a week)
Duration is a time-based amount (2 minutes, 48 hours)
These are examples of temporal amounts.
dateTime.plus(Period.ofMonths(9));
dateTime.minus(Duration.ofSeconds(20));
instant.minus(Duration.ofHours(1));
TemporalAdjuster objects represent transformations
LocalDate.now().with(TemporalAdjusters.*/next(DayOfWeek.TUESDAY));
date.with(lastDayOfMonth());
date.with(lastDayOfQuarter());
twoDaysLater = TemporalAdjusters.ofDateAdjuster(date -> date.plusDays(2));
ChronoUnit.DAYS.between(then, now)
Year.of(2015).atMonth(Month.JANUARY).atEndOfMonth().atStartOfDay();
(It turns out that some days don't have a midnight...)
java.util.TimeZone represents a zone offset and works out DST rules
java.time splits this into:
ZoneIdZoneRulesZoneOffset extends ZoneId
// what does Joda-Time's DateTime.withTimeZone() do?
offsetDateTime.atZoneSameInstant(ZoneId.of("Europe/London"));
offsetDateTime.atZoneSimilarLocal(ZoneId.of("Europe/London"));
When is Instant.now()?
Joda-Time has DateTimeUtils to allow overriding a fixed value
java.time defines a Clock class to provide the current instant and timezone, for injection
Clock.systemDefaultZone(); // default for LocalDateTime.now()
Clock.systemUTC(); // default for Instant.now()
Clock.system(ZoneId.of(someTzName)); // override default time zone
Clock.fixed(Instant.parse("2015-03-11T23:32:00Z"), ZoneOffset.UTC);
Clock.tickSeconds(UTC); // only tick 1 second at a time
Clock.tick(Clock.systemUTC(), Duration.ofMillis(1L)); // only 1ms
clock.instant(); clock.getZone(); // access the clock