Java Date Time API

Java 8 introduces new Date Time API that is easier to used than the traditional java.util.Date class.

LocalDate

java.time.LocalDate stores a date only such as 2022-01-01. No time info is stored.

Create LocalDate

Use static method now(), of() and parse() to create a date.

static method now() - Obtains the current date from the system clock in the default time-zone. Internally calls LocalDate.now(Clock.systemDefaultZone()).

1
LocalDate.now();

You can provide a ZoneId to get current date from a specific time-zone.

1
LocalDate.now(ZoneId.of("America/New_York"));

Obtains an instance of LocalDate from a year, month and day.

1
2
LocalDate.of(2022, 1, 1);
LocalDate.of(2022, Month.JANUARY, 1);

Obtain a LocalDate by parsing. You can specify a DateTimeFormatter if input is in in DateTimeFormatter.ISO_LOCAL_DATE format.
parse method throws DateTimeParseException if the text cannot be parsed

1
2
LocalDate.parse("2022-01-01");
LocalDate.parse("2022/01/01", DateTimeFormatter.ofPattern("yyyy/MM/dd"));

Accessing fields

There are many getter methods to get individual fields

  • getYear()
  • getMonth()
  • getDayOfYear()
  • getDayOfMonth()
  • getDayOfWeek()
  • getLong(TemporalField field)
1
2
3
4
5
int year = LocalDate.now().getYear();
Month month = LocalDate.now().getMonth();
int dayOfYear = LocalDate.now().getDayOfYear();
int dayOfMonth = LocalDate.now().getDayOfMonth();
DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();

Calculation methods

Use the following methods to calculate dates. All of these return a copy of LocalDate.

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusDays(long)
  • plusWeeks(long)
  • plusMonths(long)
  • plusYears(long)
  • minus(long amountToSubtract, TemporalUnit unit)
  • minus(TemporalAmount amountToSubtract)
  • minusDays(long)
  • minusWeeks(long)
  • minusMonths(long)
  • minusYears(long)
1
2
3
LocalDate.of(2022, 1, 1).plus(3, ChronoUnit.DAYS)
LocalDate.of(2022, 1, 1).plus(Period.ofDays(3))
LocalDate.now().plusDays(1);

Formatting

LocalDate.toString method outputs the date in ISO-8601 format uuuu-MM-dd. If you need a specific format, use format method and pass a java.time.format.DateTimeFormatter instance.

1
2
3
4
// formatting example
LocalDate.now().format(DateTimeFormatter.ISO_DATE); // e.g. 2022-01-01
LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); // e.g. 20220101
LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")); // e.g. 2022/01/01

Other methods

Methods to compare other date

  • int compareTo(ChronoLocalDate other)
  • boolean isAfter(ChronoLocalDate other)
  • boolean isBefore(ChronoLocalDate other)
  • boolean isEqual(ChronoLocalDate other)

Convert to LocalDate

  • atStartOfDay() - Combines this date with the time of midnight to create a LocalDateTime at the start of this date.
  • atTime(int hour, int minute) - Combines this date with a time to create a LocalDateTime.
  • atTime(int hour, int minute, int second) - Combines this date with a time to create a LocalDateTime.
  • atTime(int hour, int minute, int second, int nanoOfSecond) - Combines this date with a time to create a LocalDateTime.
  • atTime(LocalTime time) - Combines this date with a time to create a LocalDateTime.

Convert to ZonedDateTime

  • ZonedDateTime atStartOfDay(ZoneId zone) - Returns a zoned date-time from this date at the earliest valid time according to the rules in the time-zone.

convert to java.util.Date

convert to java.util.Date. First to Instant first, then use Date.from method to create a Date.

1
Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());

LocalTime

java.time.LocalTime stores a time only. No date is stored in LocalTime.

LocalTime is an immutable date-time object that represents a time, often viewed as hour-minute-second. Time is represented to nanosecond precision. For example, the value “13:45.30.123456789” can be stored in a LocalTime.

Constants

1
2
3
4
LocalTime.MIN // 00:00
LocalTime.MAX // 23:59:59.999999999
LocalTime.MIDNIGHT // 00:00
LocalTime.NOON // 12:00

Create LocalTime

use static method now() to osbtains the current time from the system clock in the default time-zone.

1
LocalTime.now();

You can provide a ZoneId to get current time for a time zone.

1
LocalTime.now(ZoneId.systemDefault());

Use of method to create LocalTime

1
2
3
4
5
LocalTime.of(8, 0); // 8:00
LocalTime.of(14, 30, 0); // 14:30

// pass 1000 nano seconds as the fourth argument
LocalTime.of(14, 30, 10, 1000); // 14:30:10.000001

Parse from a String

1
2
3
LocalTime.parse("14:30");
LocalTime.parse("14:30:00");
LocalTime.parse("00:00:00", DateTimeFormatter.ISO_LOCAL_TIME);

Accessing fields

  • getHour()
  • getMinute()
  • getSecond()
  • getNano()
  • getLong(TemporalField field)

Calculation methods

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusHours()
  • plusMinutes()
  • plusNanos()
  • plusSeconds()
  • minus(long amountToAdd, TemporalUnit unit)
  • minus(TemporalAmount amountToAdd)
  • minusHours()
  • minusMinutes()
  • minusNanos()
  • minusSeconds()

Formatting

1
2
3
LocalTime.now().format(DateTimeFormatter.ISO_TIME); // 20:54:24.015
LocalTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME); // 20:54:24.015
LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")); // 08:54:24

Other methods

truncatedTo(TemporalUnit unit) - Returns a copy of this LocalTime with the time truncated.

1
LocalTime time = LocalTime.now().truncatedTo(ChronoUnit.SECONDS);

LocalDateTime atDate(LocalDate date) - Combines this time with a date to create a LocalDateTime.

1
LocalDateTime tomorrowDateTime = LocalTime.now().atDate(LocalDate.now().plusDays(1)); // 2022-06-18T23:32:00.615737

LocalDateTime

java.time.LocalDateTime - A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.

Create LocalDateTime

use now() to get the current local date time. Provide a ZoneId to get the local time of a specific timezone.

1
2
LocalDateTime now = LocalDateTime.now();
LocalDateTime.now(ZoneOffset.UTC); // get UTC LocalDateTime 2022-06-19T18:19:32.505436

Use of() method to construct a local date time

1
LocalDateTime.of(2022, Month.JANUARY, 1, 0, 0); // 2022-01-01T00:00

parse from a String

1
2
3
4
5
LocalDateTime.parse("2022-01-01T00:00");
LocalDateTime.parse("2022-06-19T13:53:59", DateTimeFormatter.ISO_DATE_TIME)
LocalDateTime.parse("2022-06-19T13:53:59Z", DateTimeFormatter.ISO_DATE_TIME)
LocalDateTime.parse("2022-06-19T13:53:59.478775", DateTimeFormatter.ISO_DATE_TIME);
LocalDateTime.parse("2022/08/17 21:19:55", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"))

Convert an Instant to LocalDateTime

1
2
3
// instant converted to LocalDateTime in US East timezone
// 2022-06-01T00:00:00.00Z ==> 2022-05-31T20:00
LocalDateTime.ofInstant(Instant.parse("2022-06-01T00:00:00.00Z"), ZoneId.of("America/New_York"));

Accessing Fields

  • getYear()
  • getMonth()
  • getDayOfYear()
  • getDayOfMonth()
  • getDayOfWeek()
  • getHour()
  • getMinute()
  • getSecond()
  • getNano()
  • getLong(TemporalField field)

Calculation

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusDays(long)
  • plusWeeks(long)
  • plusMonths(long)
  • plusYears(long)
  • plusHours()
  • plusMinutes()
  • plusNanos()
  • plusSeconds()
  • minus(long amountToAdd, TemporalUnit unit)
  • minus(TemporalAmount amountToAdd)
  • minusDays(long)
  • minusWeeks(long)
  • minusMonths(long)
  • minusYears(long)
  • minusHours()
  • minusMinutes()
  • minusNanos()
  • minusSeconds()
1
LocalDateTime.now().plus(1, ChronoUnit.HOURS);

Formatting

1
2
3
4
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME); // 2022-06-19T13:53:59.478775
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); // 2022-06-19T13:54:39.712041
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")); // 2022/08/17 21:19:55

Other methods

toLocalDate() - gets the local date part

1
LocalDate date = LocalDateTime.now().toLocalDate(); // 2022-06-19

toLocalTime() - gets the local time part

1
LocalDateTime.now().toLocalTime(); //14:32:29.085858

atZone(ZoneId zone) - Combines this date-time with a time-zone to create a ZonedDateTime.

1
LocalDateTime.now().atZone(ZoneOffset.UTC);

ZonedDateTime

java.time.ZonedDateTime - datetime with ZoneId. represent an instant in a Timezone.

Create a ZonedDateTime

create a ZonedDateTime using now() method. Returns the current date-time using the system clock in the default time-zone.

1
2
ZonedDateTime zonedDateTimeNow = ZonedDateTime.now();
// 2023-02-17T23:25:40.460698-05:00[America/New_York]

create a ZonedDateTime using now(ZoneId zone) method.

1
2
3
4
5
ZonedDateTime utcNow = ZonedDateTime.now(ZoneOffset.UTC); 
// 2022-06-23T03:39:49.946535Z

ZonedDateTime usEastNow = ZonedDateTime.now(ZoneId.of("America/New_York"));
// 2022-06-22T23:40:02.226819-04:00[America/New_York]

create ZonedDateTime from a LocalDateTime and a ZoneId.

1
2
3
ZonedDateTime.of(LocalDateTime.parse("2022-01-01T03:00"),
ZoneId.of("America/New_York"));
// 2022-01-01T00:00-05:00[America/New_York]

create ZonedDateTime from a LocalDate, LocalTime and a ZoneId

1
2
3
ZonedDateTime.of(LocalDate.parse("2022-01-01"), LocalTime.parse("03:00"),
ZoneId.of("America/New_York"));
// 2022-01-01T00:00-05:00[America/New_York]

create an instance of ZonedDateTime from a year, month, day, hour, minute, second, nanosecond and time-zone.

1
ZonedDateTime.of(2022, 1, 1, 3, 0,0,0, ZoneId.of("America/New_York")); // 2022-01-01T03:00-05:00[America/New_York]

create an instance of ZonedDateTime from an Instant.

1
2
ZonedDateTime.ofInstant(Instant.parse("2023-01-01T00:00:00Z"), ZoneId.of("America/New_York"))
// 2022-12-31T19:00-05:00[America/New_York]

create ZonedDateTime by parsing String

1
2
3
ZonedDateTime.parse("2023-01-01T00:00-05:00[America/New_York]");
ZonedDateTime.parse("2023-06-01T00:00-04:00[America/New_York]")
ZonedDateTime.parse("2007-12-03T10:15:30Z", DateTimeFormatter.ISO_DATE_TIME);

toString

toString method Outputs this date-time as a String, such as 2007-12-03T10:15:30+01:00[Europe/Paris].
The format consists of the LocalDateTime followed by the ZoneOffset.

Accessing Fields

  • getYear()
  • getMonth()
  • getDayOfYear()
  • getDayOfMonth()
  • getDayOfWeek()
  • getHour()
  • getMinute()
  • getSecond()
  • getNano()
  • getLong(TemporalField field)

ZonedDateTime has getZone() method to return ZoneId value and getOffset() method to get ZoneOffset.

1
2
ZonedDateTime.now(ZoneId.of("America/New_York")).getZone(); // returns ZoneId America/New_York
ZonedDateTime.now(ZoneId.of("America/New_York")).getOffset(); // returns ZoneOffset -04:00 or -5:00

Calculation

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusDays(long)
  • plusWeeks(long)
  • plusMonths(long)
  • plusYears(long)
  • plusHours()
  • plusMinutes()
  • plusNanos()
  • plusSeconds()
  • minus(long amountToAdd, TemporalUnit unit)
  • minus(TemporalAmount amountToAdd)
  • minusDays(long)
  • minusWeeks(long)
  • minusMonths(long)
  • minusYears(long)
  • minusHours()
  • minusMinutes()
  • minusNanos()
  • minusSeconds()
1
2
ZonedDateTime.now(ZoneId.of("America/New_York")).plusDays(1);
ZonedDateTime.now(ZoneId.of("America/New_York")).plus(1, ChronoUnit.HOURS);

Formatter

1
2
3
4
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ISO_DATE_TIME); // 2022-08-17T21:00:26.343-04:00[America/New_York]
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); // 2022-08-17T21:00:26.343
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 2022-08-17T21:01:54.186-04:00
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss z")); // 2022/08/17 21:01:13 EDT

Convert to Different Zone

withZoneSameInstant = used to convert between differnet timezone

1
2
3
4
// convert between different timezone
// find time in Singapore timezone. wow! it is 13 hours ahead....
ZonedDateTime singaporeTime = estTime.withZoneSameInstant(ZoneId.of("Asia/Singapore")); // 2022-01-01T13:00+08:00[Asia/Singapore]
System.out.println("find time in Singapore timezone: " + singaporeTime);

Convert to java.util.Date

1
Date.from(ZonedDateTime.now().toInstant());

Convert from java.util.Date

1
2
3
Date date = DateUtils.parseDate("2024-06-01", "yyyy-MM-dd");
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("US/Eastern"));
System.out.println(zonedDateTime); // 2024-06-01T00:00-04:00[US/Eastern]

Other methods

  • toLocalDate - gets the LocalDate part of ZonedDateTime
  • toLocalTime - gets the LocalTime part of ZonedDateTime
  • toLocalDateTime - gets the LocalDateTime part of ZonedDateTime
1
2
3
4
5
6
7
8
9
ZonedDateTime now = ZonedDateTime.parse("2022-06-20T10:15:30-04:00[America/New_York]");
now.toLocalDate();
// ==> 2022-07-06

now.toLocalTime();
// ==> 00:13:10.163026

now.toLocalDateTime();
// ==> 2022-07-06T00:13:10.163026

OffsetDateTime

OffsetDateTime - contains date-time and an offset such as 2022-01-01T03:00:00-05:00.

Difference bewteen OffsetDateTime, ZonedDateTime and Instant - see Javadoc

“OffsetDateTime, ZonedDateTime and Instant all store an instant on the time-line to nanosecond precision. Instant is the simplest, simply representing the instant. OffsetDateTime adds to the instant the offset from UTC/Greenwich, which allows the local date-time to be obtained. ZonedDateTime adds full time-zone rules.”

Create OffsetDateTime

create an OffsetDateTime using now() method:

1
2
3
4
5
6
7
8
OffsetDateTime utcNow = OffsetDateTime.now(ZoneOffset.UTC); 
// 2022-06-23T03:38:41.164348Z

OffsetDateTime usEastNow = OffsetDateTime.now(ZoneId.of("America/New_York"));
// 2022-06-22T23:39:07.345612-04:00

OffsetDateTime usEastNow = OffsetDateTime.now(ZoneOffset.of("-04:00"));
// 2022-06-22T23:39:07.345612-04:00

create OffsetDateTime from a LocalDateTime and a ZoneOffset.

1
2
3
OffsetDateTime.of(LocalDateTime.parse("2022-01-01T15:00"),
ZoneOffset.of("-05:00"));
// 2022-01-01T15:00-05:00

create OffsetDateTime from a LocalDate, LocalTime and a ZoneOffset

1
2
3
OffsetDateTime.of(LocalDate.parse("2022-01-01"), LocalTime.parse("15:00"),
ZoneOffset.of("-05:00"));
// 2022-01-01T15:00-05:00

create an instance of OffsetDateTime from a year, month, day, hour, minute, second, nanosecond and ZoneOffset.

1
2
OffsetDateTime.of(2022, 6, 1, 3, 0,0,0, ZoneOffset.of("-04:00")); 
// 2022-06-01T03:00-04:00

create an instance of OffsetDateTime from an Instant.

1
2
OffsetDateTime.ofInstant(Instant.parse("2022-01-01T00:00:00Z"), ZoneId.of("Asia/Tokyo")); 
// 2022-01-01T09:00+09:00

create OffsetDateTime by parsing String

1
2
OffsetDateTime.parse("2022-12-03T10:15:30+09:00");
OffsetDateTime.parse("2022-12-03T10:15:30+09:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);

Accessing Fields

  • getYear()
  • getMonth()
  • getDayOfYear()
  • getDayOfMonth()
  • getDayOfWeek()
  • getHour()
  • getMinute()
  • getSecond()
  • getNano()
  • getLong(TemporalField field)

OffsetDateTime has getOffset() method to return ZoneOffset

1
OffsetDateTime.now(ZoneOffset.of("-04:00")).getOffset(); // returns ZoneOffset -04:00

methods to get part of an OffsetDateTime

  • toLocalDate()
  • toLocalDateTime()
  • toLocalTime()
  • toOffsetTime()

Calculation

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusDays(long)
  • plusWeeks(long)
  • plusMonths(long)
  • plusYears(long)
  • plusHours()
  • plusMinutes()
  • plusNanos()
  • plusSeconds()
  • minus(long amountToAdd, TemporalUnit unit)
  • minus(TemporalAmount amountToAdd)
  • minusDays(long)
  • minusWeeks(long)
  • minusMonths(long)
  • minusYears(long)
  • minusHours()
  • minusMinutes()
  • minusNanos()
  • minusSeconds()
1
2
OffsetDateTime.now(ZoneOffset.of("-04:00")).plusDays(1);
OffsetDateTime.now(ZoneOffset.of("-04:00")).plus(1, ChronoUnit.HOURS);

Formatter

1
2
OffsetDateTime.now(ZoneOffset.of("-04:00")).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 2022-06-23T00:01:19.596163-04:00
OffsetDateTime.now(ZoneOffset.of("-04:00")).format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss X")); // 2022/06/23 00:02:48 -04

Other methods

atZoneSameInstant(ZoneId zone) - convert to ZonedDateTime by providing a ZoneId

1
OffsetDateTime.now(ZoneOffset.of("-04:00")).atZoneSameInstant(ZoneId.of("America/New_York"));

toInstant() - convert to Instant

1
OffsetDateTime.now(ZoneOffset.of("-04:00")).toInstant();

toEpochSecond() - get number of seconds since the epoch of 1970-01-01T00:00:00Z.

1
OffsetDateTime.now(ZoneOffset.of("-04:00")).toEpochSecond();

Convert to java.util.Date

1
Date date = Date.from(OffsetDateTime.now(ZoneOffset.of("-04:00")).toInstant());

Instant

java.time.Instant - An instantaneous point on the time-line.

From javadoc:

This class models a single instantaneous point on the time-line. This might be used to record event time-stamps in the application.

The range of an instant requires the storage of a number larger than a long. To achieve this, the class stores a long representing epoch-seconds and an int representing nanosecond-of-second, which will always be between 0 and 999,999,999. The epoch-seconds are measured from the standard Java epoch of 1970-01-01T00:00:00Z where instants after the epoch have positive values, and earlier instants have negative values. For both the epoch-second and nanosecond parts, a larger value is always later on the time-line than a smaller value.

Create an Instant

now() - create Instant from current epoch time.

1
Instant now = Instant.now(); // 2022-06-22T03:20:53.293075Z

ofEpochMilli(long epochMilli) - create Instant using milliseconds from the epoch of 1970-01-01T00:00:00Z.

1
Instant.ofEpochMilli(1655869466829L); // 2022-06-22T03:44:26.829Z

ofEpochSecond(long epochSecond) - create Instant using seconds from the epoch of 1970-01-01T00:00:00Z.

1
Instant.ofEpochSecond(1655869466L); // 2022-06-22T03:44:26Z

parse() - parse an Instant from epoch time, such as “2022-06-01T00:00:00.00Z”.

1
Instant.parse("2022-06-01T00:00:00.00Z")

Calculation

  • plus(long amountToAdd, TemporalUnit unit)
  • plus(TemporalAmount amountToAdd)
  • plusMillis(long millisToAdd)
  • plusNanos(long nanosToAdd)
  • plusSeconds(long secondsToAdd)
  • minus(long amountToSubtract, TemporalUnit unit)
  • minus(TemporalAmount amountToSubtract)
  • minusMillis(long millisToSubtract)
  • minusNanos(long nanosToSubtract)
  • minusSeconds(long secondsToSubtract)
1
2
Instant.now().plus(10, ChronoUnit.HOURS);
Instant.now().plus(Duration.ofHours(10));

Other methods

getEpochSecond() - Gets the number of seconds from the Java epoch of 1970-01-01T00:00:00Z.

1
Instant.now().getEpochSecond(); // 1656043919

toEpochMilli() - returns a long representing the number of milliseconds from the epoch of 1970-01-01T00:00:00Z.

1
Instant.now().toEpochMilli(); // 1655869466829

getLong(TemporalField field)
Gets the value of the specified field from this instant as a long.

getNano() - Gets the number of nanoseconds from the start of the second.

1
Instant.now().getNano();

Compare with other Instant

  • isAfter(Instant otherInstant)
  • isBefore(Instant otherInstant)

Convert to jva.util.Date

1
Date date = Date.from(Instant.now());

ZoneId

java.time.ZoneId - A time-zone ID, such as America/New_York.

To create a ZoneId

1
2
3
4
ZoneId.of("America/New_York");
ZoneId.of("US/Eastern"); // It's a link to America/New_York. US/Eastern is the old name. better to use America/New_York
ZoneId.of("Asia/Tokyo");
ZoneId.of("UTC"); // UTC TimeZone

get system default timezone

1
ZoneId.systemDefault();

To list all available ZoneIds

1
ZoneId.getAvailableZoneIds().forEach(System.out::println);

The time zones are listed in this wiki: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

ZoneOffset

java.time.ZoneOffset - a subclass of ZoneId. It is a time-zone offset from UTC, such as -04:00.

ZoneOffset.UTC is a constatn representing the UTC.

create a ZoneOffset

1
2
3
ZoneOffset.UTC
ZoneOffset.of("-04:00")
ZoneOffset.ofHours(-5)

DateTimeFormatter

java.time.format.DateTimeFormatter is the formatter for printing and parsing date-time objects.

DateTimeFormatter Constants

  • DateTimeFormatter.BASIC_ISO_DATE
  • DateTimeFormatter.ISO_DATE
  • DateTimeFormatter.ISO_DATE_TIME
  • DateTimeFormatter.ISO_INSTANT
  • DateTimeFormatter.ISO_LOCAL_DATE
  • DateTimeFormatter.ISO_LOCAL_DATE_TIME
  • DateTimeFormatter.ISO_LOCAL_TIME
  • DateTimeFormatter.ISO_OFFSET_DATE
  • DateTimeFormatter.ISO_OFFSET_DATE_TIME
  • DateTimeFormatter.ISO_OFFSET_TIME
  • DateTimeFormatter.ISO_ORDINAL_DATE
  • DateTimeFormatter.ISO_TIME
  • DateTimeFormatter.ISO_WEEK_DATE
  • DateTimeFormatter.ISO_ZONED_DATE_TIME
  • DateTimeFormatter.FC_1123_DATE_TIME

Use DateTimeFormatter to parse a DateTime String

1
2
// parse using DateTime
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2022-06-26T17:05:41-04:00[America/New_York]");

Use DateTimeFormatter to format datetime

1
2
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ISO_INSTANT);
// ==> "2022-06-24T04:37:40.146679Z"

Create by ofPattern method

ofPattern(String) - Create DateTimeFormatter using pattern. For details on the Pattern symbol and their meaning, see javadoc

1
2
ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ofPattern("yyyy MM dd HH:mm:ss"));
// ==> "2022 06 24 00:41:10"

Create by ofLocalizedDate method

create locale specific date time format using the following method

  • ofLocalizedDate(FormatStyle)
  • ofLocalizedTime(FormatStyle)
  • ofLocalizedDateTime(FormatStyle)

Usage

1
2
3
4
5
6
7
8
9
10
11
LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));
// ==> "6/24/22"

LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
// ==> "Friday, June 24, 2022"

ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT));
// ==> "6/24/22, 12:47 AM"

ZonedDateTime.now(ZoneId.of("America/New_York")).format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
// ==> "Friday, June 24, 2022 at 12:46:26 AM Eastern Daylight Time"

TemporalAmount Interface

java.time.temporal.TemporalAmount

From javadoc:

Framework-level interface defining an amount of time, such as “6 hours”, “8 days” or “2 years and 3 months”.
This is the base interface type for amounts of time. An amount is distinct from a date or time-of-day in that it is not tied to any specific point on the time-line.
Period is a date-based implementation, storing years, months and days. Duration is a time-based implementation, storing seconds and nanoseconds, but providing some access using other duration based units such as minutes, hours and fixed 24-hour days.

Period

java.time.period

A date-based amount of time in the ISO-8601 calendar system, such as ‘2 years, 3 months and 4 days’.

ISO-8601 period format is used by parse() and toString() method. ISO-8601 Period has the following format:

1
P(n)Y(n)M(n)DT(n)H(n)M(n)S

Create Period

Create a Period using ofXXX static methods

  • of(int years, int months, int days)
  • ofDays(int days)
  • ofMonths(int months)
  • ofWeeks(int weeks)
  • ofYears(int years)
1
2
3
4
5
6
7
8
Period.of(1,2,0);
// ==> P1Y2M

Period.ofYears(-1);
// ==> P-1Y

Period.ofWeeks(100);
// ==> P700D

between(LocalDate startDateInclusive, LocalDate endDateExclusive)

1
2
Period.between( LocalDate.parse("2022-02-01"), LocalDate.parse("2022-03-15"));
// ==> P1M14D

parse(CharSequence text) - Obtains a Period from a text string in ISO-8601 period format.

1
2
Period.parse("P1Y2M3W4D");
// ==> P1Y2M25D

Calculation

  • plus(TemporalAmount amountToAdd)
  • plusDays(long daysToAdd)
  • plusMonths(long monthsToAdd)
  • plusYears(long yearsToAdd)
  • minus(TemporalAmount amountToSubtract)
  • minusDays(long daysToSubtract)
  • minusMonths(long monthsToSubtract)
  • minusYears(long yearsToSubtract)
  • multipliedBy(int scalar)
  • negated()
1
2
Period.ofYears(1).plus(Period.ofMonths(2));
// ==> P1Y2M

Accessors

  • get(TemporalUnit unit)
  • getDays()
  • getMonths()
  • getYears()
1
2
Period.ofMonths(3).get(ChronoUnit.MONTHS);
// ==> 3

Other methods

normalized() - return a copy of normalized Period.

1
2
3
4
Period.ofWeeks(20).normalized()
// ==> P140D
Period.ofMonths(30).normalized()
// ==> P2Y6M

isNegative() - Checks if any of the three units of this period are negative.

isZero() - Checks if all three units of this period are zero.

Duration

java.time.Duration - A time-based amount of time

Create Duration

  • ofDays(long days)
  • ofHours(long hours)
  • ofMillis(long millis)
  • ofMinutes(long minutes)
  • ofNanos(long nanos)
  • ofSeconds(long seconds)
  • ofSeconds(long seconds, long nanoAdjustment)
1
2
3
4
Duration.ofDays(1);
// ==> PT24H
Duration.ofSeconds(2);
// ==> PT2S

between(Temporal startInclusive, Temporal endExclusive) - calculate Duration by finding the Duration between two times.

1
2
Duration.between(LocalTime.parse("10:00:00"),LocalTime.parse("11:00:00"));
// ==> PT1H

Calculation

  • plus (long amountToAdd, TemporalUnit unit)
  • plus (Duration duration)
  • plusDays (long daysToAdd)
  • plusHours (long hoursToAdd)
  • plusMillis(long millisToAdd)
  • plusMinutes (long minutesToAdd)
  • plusNanos (long nanosToAdd)
  • plusSeconds (long secondsToAdd)
  • minus (long amountToSubtract, TemporalUnit unit)
  • minus (Duration duration)
  • minusDays (long daysToSubtract)
  • minusHours (long hoursToSubtract)
  • minusMillis (long millisToSubtract)
  • minusMinutes (long minutesToSubtract)
  • minusNanos (long nanosToSubtract)
  • minusSeconds (long secondsToSubtract)
  • multipliedBy (long multiplicand)
  • dividedBy(long divisor)
  • dividedBy(Duration divisor)
  • negated()
1
2
3
4
 Duration.ofSeconds(2).plus(2, ChronoUnit.SECONDS);
// ==> PT4S
Duration.ofSeconds(60).multipliedBy(10);
// ==> PT10M

TemporalUnit Interface

java.time.temporal.TemporalUnit Interface - A unit of date-time, such as Days or Hours.

Implementations are ChronoUnit and Unit. Both are enum. The most commonly used units are defined in ChronoUnit.

ChronoUnit

java.time.temporal.ChronoUnit - an Enum that implements TemporalUnit Interface. Unites for date and time.

ChronoUnit Enum Constants

  • CENTURIES
  • DAYS
  • DECADES
  • ERAS
  • FOREVER
  • HALF DAYS
  • HOURS
  • MICROS
  • MILLENNIA
  • MILLIS
  • MINUTES
  • MONTHS
  • NANOS
  • SECONDS
  • WEEKS
  • YEARS

ChronoUnit.between() - To get the time between two temporal object

1
2
3
4
5
6
ChronoUnit.MONTHS.between(ZonedDateTime.of(LocalDate.parse("2022-01-01"), LocalTime.parse("03:00"),
ZoneId.of("America/New_York")), ZonedDateTime.now(ZoneId.of("America/New_York")));
// ==> 5

ChronoUnit.HOURS.between(LocalTime.parse("11:00"), LocalTime.parse("13:00"));
// ==> 2

ChronoUnit.getDuration() - gets estimate duraration of this ChronoUnit.

1
2
ChronoUnit.HOURS.getDuration();
// ==> PT1H

ChronoUnit is often used for Date-Time calculation.

1
2
3
4
5
6
LocalDate threeDaysLater = LocalDate.of(2022, 1, 1).plus(3, ChronoUnit.DAYS)

LocalDateTime oneHourEarlier = LocalDateTime.now().minus(1, ChronoUnit.HOURS);

// truncatedTo
LocalTime time = LocalTime.now().truncatedTo(ChronoUnit.SECONDS);

TemporalField Insterface

java.time.temporal.TemporalField Interface is used to access a field of a Temporal. ChronoField is the most used implementation.

A field of date-time, such as month-of-year or minute-of-hour.

ChronoField

java.time.temporal.ChronoField - Enum that implements TemporalField insterface.

This set of fields provide field-based access to manipulate a date, time or date-time.

Enum Constants:

  • ALIGNED_DAY_OF_WEEK_IN_MONTH
  • ALIGNED_DAY_OF_WEEK_IN_YEAR
  • ALIGNED_WEEK_OF_MONTH
  • ALIGNED_WEEK_OF_YEAR
  • AMPM_OF_DAY
  • CLOCK_HOUR_OF_AMPM
  • CLOCK_HOUR_OF_DAY
  • DAY_OF_MONTH
  • DAY_OF_WEEK
  • DAY_OF_YEAR
  • EPOCH_DAY
  • ERA
  • HOUR_OF_AMPM
  • HOUR_OF_DAY
  • INSTANT_SECONDS
  • MICRO_OF_DAY
  • MICRO_OF_SECOND
  • MILLI_OF_DAY
  • MILLI_OF_SECOND
  • MINUTE_OF_DAY
  • MINUTE_OF_HOUR
  • MONTH_OF_YEAR
  • NANO_OF_DAY
  • NANO_OF_SECOND
  • OFFSET_SECONDS
  • PROLEPTIC_MONTH
  • SECOND_OF_DAY
  • SECOND_OF_MINUTE
  • YEAR
  • YEAR_OF_ERA

Fields are how humans generally refer to time, which is in parts.

1
2
3
4
5
6
7
8
9
10
11
LocalDateTime now = LocalDateTime.now();
if(now.isSupported(ChronoField.MICRO_OF_SECOND)) {
System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
}

System.out.println(now.get(ChronoField.MINUTE_OF_HOUR));
System.out.println(now.get(ChronoField.DAY_OF_WEEK));
System.out.println(now.get(ChronoField.DAY_OF_MONTH));
System.out.println(now.get(ChronoField.MONTH_OF_YEAR));
System.out.println(now.get(ChronoField.YEAR));
System.out.println(now.get(ChronoField.YEAR_OF_ERA));

getDisplayName - Gets the display name for the field in the requested locale.

1
2
3
4
5
6
7
8
9
10
11
ChronoField.HOUR_OF_DAY.getDisplayName(Locale.US);
// ==> "hour"

ChronoField.DAY_OF_WEEK.getDisplayName(Locale.US);
// ==> "day of the week"

ChronoField.DAY_OF_WEEK.getDisplayName(Locale.CHINA);
// ==> "工作日"

ChronoField.HOUR_OF_DAY.getDisplayName(Locale.KOREA);
// ==> "시"

ChronoUnit VS ChronoField

Units are used to measure a quantity of time

fields are how humans generally refer to time, which is in parts.

To define a complete point on the time-line you have to have a set of linked fields, eg:

  • second-of-minute
  • minute-of-hour
  • hour-of-day
  • day-of-month
  • month-of-year
  • year (-of-forever)

reference: Stackoverflow - java.time.temporal.ChronoUnit VS java.time.temporal.ChronoField

Temporal Interface

java.time.Temporal Interface

Framework-level interface defining read-write access to a temporal object, such as a date, time, offset or some combination of these.

Temporal interface methods

  • isSupported(TemporalUnit)
  • with(TemporalAdjuster)
  • with(TemporalField, long)
  • plus(TemporalAmount)
  • plus(long, TemporalUnit)
  • minus(TemporalAmount)
  • minus(long, TemporalUnit)
  • until(Temporal, TemporalUnit)

Known implementation classes

  • LocalDate
  • LocalDateTime
  • LocalTime
  • OffsetDateTime
  • OffsetTime
  • ZonedDateTime

The following classes also implement Temporal interface but are less used

TemporalAccessor Interface

java.time.temporal.TemporalAccessor Interface

Framework-level interface defining read-only access to a temporal object, such as a date, time, offset or some combination of these.

Temporal Classes such as LocalDateTime, ZonedDateTime implements this Interface.

TemporalAccessor interface methods:

  • int get(TemporalField field)
  • long getLong(TemporalField field)
  • boolean isSupported(TemporalField field)
  • default R query(TemporalQuery query)
  • default ValueRange range(TemporalField field)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
LocalDateTime.now().isSupported(ChronoField.DAY_OF_YEAR);
// ==> true

LocalDate.now().get(ChronoField.DAY_OF_WEEK);
// ==> 6

LocalDateTime.now().getLong(ChronoField.NANO_OF_DAY);
// gets nano second of the day

LocalDateTime.now().range(ChronoField.DAY_OF_YEAR);
// ==> 1 - 365

ZoneId zoneId = ZonedDateTime.now().query(TemporalQueries.zone());
// gets ZoneId such as America/New_York

Reference