home

Date & Time

Overview

Cheat Sheet

<!-- Instant -->
Instant.now();

<!-- LocalDate -->
LocalDate.now();
LocalDate.of();
LocalDate.parse(String);

Date & Time Constants

ChronoUnit

enum ChronoUnit implements TemporalUnit {
    NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, DAYS, WEEKS, MONTHS, YEARS, DECADES, CENTURIES, 
    MILLENNIA, ERAS, FOREVER
}

ChronoField

enum ChronoField implements TemporalField {
    NANO_OF_SECOND, NANO_OF_DAY, MICRO_OF_SECOND, MICRO_OF_DAY, MILLI_OF_SECOND, MILLI_OF_DAY, SECOND_OF_MINUTE, 
    SECOND_OF_DAY, MINUTE_OF_HOUR, MINUTE_OF_DAY, HOUR_OF_AMPM, CLOCK_HOUR_OF_AMPM, HOUR_OF_DAY, 
    CLOCK_HOUR_OF_DAY, AMPM_OF_DAY, DAY_OF_WEEK, ALIGNED_DAY_OF_WEEK_IN_MONTH, ALIGNED_DAY_OF_WEEK_IN_YEAR, 
    DAY_OF_MONTH, DAY_OF_YEAR, EPOCH_DAY, ALIGNED_WEEK_OF_MONTH, ALIGNED_WEEK_OF_YEAR, MONTH_OF_YEAR, 
    PROLEPTIC_MONTH, YEAR_OF_ERA, YEAR, ERA, INSTANT_SECONDS, OFFSET_SECONDS    
}

See also: Difference between ChronoUnit and ChronoField

Instant

Creating an Instant

// Capture the current moment in UTC
Instant.now();              // 2018-11-28T01:51:48.847Z

// Get the epoch
Instant.EPOCH;              // 1970-01-01T00:00:00Z

// Reminder: 1000 milliseconds = 1 second
Instant.ofEpochMilli(1000); // 1970-01-01T00:00:01Z

Further Reading

Creating an Instant from a Temporal Object

// ZonedDateTime is supported
Instant.from(ZonedDateTime.now()); // 2018-11-29T03:38:33.905Z

// LocalDateTime is not supported
Instant.from(LocalDate.now()); // UnsupportedTemporalTypeException: Unsupported field: InstantSeconds

Duration

A Duration measures an amount of time using time-based values, i.e. hours, minutes, seconds..

The Java™ Tutorials

Creating a Duration

Creating a Duration with Constants

// Creating a Duration with ofNanos, ofSeconds, ofMillis, ofMinutes, ofHours, ofDays
Duration.ofNanos(1); // PT0.000000001S
Duration.ofDays(1);  // PT24H

Creating a Duration from Duration Between Temporals

// Using Instant
Duration.between(Instant.EPOCH, Instant.now()); // PT428714H19M29.54S

// Using LocalTime
LocalTime now = LocalTime.now();
Duration.between(now.minusHours(1).minusMinutes(30).minusSeconds(15), now); // PT1H30M15S

// LocalDate is NOT supported
// Duration.between(LocalDate.now(), LocalDate.now())
// java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds

Reading a Duration

Duration d = Duration.between(Instant.EPOCH, Instant.now());
d.toDays()  // 17864
d.toHours() // 428738
// Also available: toNanos(), toMillis(), getSeconds(), toMinutes()

Why can't I get a duration in minutes or hours in java.time?

.. that get(TemporalUnit) is essentially a framework-level method - it is not designed for day-today use. Unfortunately the method name get does not imply this, resulting in bugs like calling get(ChronoUnit.MINUTES) on Duration

LocalDate

Creating a LocalDate

LocalDate.now();                // 2018-11-25
LocalDate.of(1984, 9, 3);       // 1984-09-03
LocalDate.parse("1984-09-03");  // 1984-09-03

Reading a LocalDate

LocalDate ld = LocalDate.of(1984, 9, 3);
ld.getDayOfWeek();  // DayOfWeek.MONDAY
ld.getDayOfMonth(); // 3
ld.getDayOfYear();  // 247
LocalDate ld = LocalDate.of(1984, 9, 3);
ld.getMonth();      // Month.SEPTEMBER
ld.getMonthValue(); // 9

Reading Various Properties from a LocalDate

LocalDate ld = LocalDate.of(1984, 9, 3);
ld.lengthOfMonth(); // 30
ld.isLeapYear();    // true
ld.lengthOfYear();  // 366 

Updating a LocalDate

Heads Up! java.time.LocalDate is an immutable class an update methods return new instances instead of updating the instance itself!

Updating a LocalDate with Periods

LocalDate ld = LocalDate.of(1983, 9, 3);
ld.plus(Period.ofYears(1));  // 1984-09-03 --> This is most likely what you want.
ld.plus(Period.ofDays(365)); // 1984-09-02 --> It is not the 3rd of 84 due to leap year!

Period

A Period measures an amount of time using date-based values, i.e. years, months, days..

The Java™ Tutorials

Why can I not get number of calendar days from a Period?

.. it is not possible from a Period to deduce the actual number of calendar days in the period. A Period is not tied to specific dates, once constructed in the way you show, it loses track of the actual calendar dates.

For example your first period represents a period of 1 month and 1 day. But the period does not care which month. It is simply a concept of "a month and a day".

To get number of days between two dates, use ChronoUnit.DAYS.between(Temporal, Temporal) ..

How to calculate the number of days in a period? - StackOverflow

Creating a Period

// Period of years, months, days
Period.of(1, 1, 1); // P1Y1M1D
Period.ofDays(45);  // P45D
// also available: ofMonths, ofYears

LocalTime

Creating a LocalTime

Creating a new LocalTime

LocalTime.of(22, 30);     // 22:30
LocalTime.of(22, 30, 45); // 22:30:45
LocalTime.parse("22:30"); // 22:30
LocalTime.now();          // 22:57:36.162

LocalDateTime

Creating a LocalDateTime

Creating a LocalDateTime using an Instant

Instant now = Instant.now();
LocalDateTime.ofInstant(now, ZoneOffset.UTC); // 2018-11-28
LocalDateTime.ofInstant(now, ZoneId.of("America/Toronto")); // 2018-11-27

ZonedDateTime

Creating a ZonedDateTime

ZonedDateTime.now();                            // 2018-11-28T23:30:08.454-05:00[America/Toronto]
ZonedDateTime.now(Clock.systemDefaultZone());   // 2018-11-28T23:30:08.456-05:00[America/Toronto]
ZonedDateTime.now(Clock.systemUTC());           // 2018-11-29T04:30:08.456Z

ZonedDateTime from LocalDate

LocalDate ld = LocalDate.of(1984, 9, 3);
// Basically attaching time zone information to a particular date
ld.atStartOfDay(ZoneId.of("America/Toronto")); // 1984-09-03T00:00-04:00[America/Toronto]
ld.atStartOfDay(ZoneId.of("Europe/Istanbul")); // 1984-09-03T00:00+03:00[Europe/Istanbul]

Examples

Find Number of Days between LocalDates


Daylight Saving Times

final Set<ZonedDateTime> dayLightSavingZonedDateTimes = new HashSet<>();

ZoneId.getAvailableZoneIds().forEach(zoneId -> {
    LocalDateTime dateTime = LocalDateTime.of(LocalDate.of(2018, 1, 1), LocalTime.of(0, 0, 0));
    ZonedDateTime now = ZonedDateTime.of(dateTime, ZoneId.of(zoneId));
    while (2018 == now.getYear()) {
        int hour = now.getHour();
        now = now.plusHours(1);
        if (now.getHour() == hour) {
            dayLightSavingZonedDateTimes.add(now);
        }
    }
});

dayLightSavingZonedDateTimes.stream().limit(5).forEach(time -> System.out.println(time));

// 2018-11-04T01:00-05:00[America/Indiana/Petersburg]
// 2018-11-04T01:00-10:00[US/Aleutian]
// 2018-10-28T02:00+01:00[Europe/Brussels]
// 2018-10-28T03:00+02:00[Europe/Sofia]
// 2018-10-28T02:00+01:00[Europe/Vienna]

Day of the Programmer

// Print the Day of the Programmer (the 256th day of the year) for 2011 and 2012
IntStream.rangeClosed(2011, 2012).forEach(year -> {
    LocalDate programmersDay = LocalDate.of(year, 1, 1).plusDays(255);
    System.out.println(programmersDay);
});

// 2011-09-13
// 2012-09-12

References

TODO

It's not possible to do that directly, since the LocalDateTime family of objects has no notion of what time zone they're in. Thus time zone information needs to be supplied to find the time relative to the epoch, which is in UTC.

How to get milliseconds from LocalDateTime in Java 8 - StackOverflow