1.4 Date and Time APIs (java.time)

Key Takeaways

  • The java.time API classes (LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant) are immutable and thread-safe, returning new temporal instances upon modification.
  • Period represents date-based units (years, months, days) while Duration represents time-based units (hours, minutes, seconds, nanos); they cannot be used interchangeably.
  • DateTimeFormatter formats and parses dates, times, and zones, throwing an UnsupportedTemporalTypeException when formatting fields missing from the target temporal object.
  • Daylight Saving Time transitions adjust wall-clock times in ZonedDateTime calculations, where adding a Period preserves local time while adding a Duration computes exact elapsed hours.
Last updated: September 2026

Date and Time APIs (java.time)

Java's Date-Time API (java.time, JSR-310) provides a comprehensive, immutable, and thread-safe framework for date and time manipulation. The 1Z0-830 exam heavily tests temporal class distinctions, immutability pitfalls, Period vs. Duration arithmetic, DateTimeFormatter patterns, and Daylight Saving Time (DST) zone adjustments.


1. Core Temporal Types and Architecture

+-------------------------------------------------------------------------+
|                           java.time Framework                           |
|                                                                         |
|  +--------------------+  +--------------------+                         |
|  |     LocalDate      |  |     LocalTime      |                         |
|  |  (2026-09-02)      |  |  (14:30:45.123)    |                         |
|  +---------+----------+  +---------+----------+                         |
|            |                       |                                    |
|            +----------+------------+                                    |
|                       |                                                 |
|             +---------v----------+                                      |
|             |   LocalDateTime    |                                      |
|             | (2026-09-02T14:30) |                                      |
|             +---------+----------+                                      |
|                       | + ZoneId ("America/New_York")                   |
|             +---------v----------+         +-------------------------+  |
|             |   ZonedDateTime    | ------> |         Instant         |  |
|             | (Date+Time+ZoneId) |         | (Epoch Timestamp in UTC)|  |
|             +--------------------+         +-------------------------+  |
+-------------------------------------------------------------------------+

Primary Temporal Classes

ClassRepresentsSample OutputTypical Factory Methods
LocalDateDate without time or zone2026-09-02LocalDate.of(2026, 9, 2), LocalDate.parse("2026-09-02")
LocalTimeTime without date or zone14:30:15.999LocalTime.of(14, 30), LocalTime.parse("14:30:15")
LocalDateTimeDate and time without zone2026-09-02T14:30:15LocalDateTime.of(date, time), LocalDateTime.now()
ZonedDateTimeDate and time with full timezone rules2026-09-02T14:30:15-04:00[America/New_York]ZonedDateTime.of(dt, zoneId), ZonedDateTime.now()
OffsetDateTimeDate and time with fixed UTC offset2026-09-02T14:30:15-04:00OffsetDateTime.of(dt, zoneOffset)
InstantInstantaneous point on time-line (UTC epoch)2026-09-02T18:30:15.999ZInstant.now(), Instant.ofEpochMilli(ms)

[!NOTE] Month values in java.time are 1-indexed (1 = January, 12 = December), or referenced via the java.time.Month enum (Month.SEPTEMBER). Attempting to construct an invalid date (e.g., LocalDate.of(2026, 2, 29)) immediately throws a runtime java.time.DateTimeException.


2. Immutability and Temporal Arithmetic

All core classes in java.time are immutable. Methods that alter dates or times (plusDays(), minusHours(), withYear()) return a new object without modifying the original instance.

LocalDate date = LocalDate.of(2026, 1, 15);
date.plusDays(10); // RETURN VALUE IGNORED!
System.out.println(date); // Prints 2026-01-15 (Unchanged!)

// Correct usage:
date = date.plusDays(10);
System.out.println(date); // Prints 2026-01-25

Fluent Adjustment Methods

  • plusYears(long), plusMonths(long), plusWeeks(long), plusDays(long)
  • minusHours(long), minusMinutes(long), minusSeconds(long), minusNanos(long)
  • withMonth(int), withDayOfMonth(int), withHour(int) (replaces specific field)

3. Period vs. Duration

Java strictly separates date-based amounts (Period) from time-based amounts (Duration):

FeaturePeriodDuration
Unit FocusYears, Months, Days (Date-based)Days, Hours, Minutes, Seconds, Nanos (Time-based)
Compatible TypesLocalDate, LocalDateTime, ZonedDateTimeLocalTime, LocalDateTime, ZonedDateTime, Instant
Incompatible TypesLocalTime, Instant (Throws UnsupportedTemporalTypeException)LocalDate (Throws UnsupportedTemporalTypeException)
Factory CreationPeriod.of(1, 2, 15), Period.ofDays(10)Duration.ofHours(5), Duration.ofMinutes(30)
Between MethodPeriod.between(localDate1, localDate2)Duration.between(temporal1, temporal2)
// The Static Factory Chaining Trap
Period p = Period.ofYears(1).ofMonths(6).ofDays(3); 
// WARNING: ofXXX() are STATIC methods. Chaining does not combine them!
// The variable 'p' contains only Period.ofDays(3)!

// Correct combination:
Period correctPeriod = Period.of(1, 6, 3);

// Type Mismatch Exceptions
LocalTime time = LocalTime.of(10, 0);
// time.plus(Period.ofDays(1)); // RUNTIME ERROR: UnsupportedTemporalTypeException!

LocalDate day = LocalDate.of(2026, 5, 1);
// Duration.between(day, day.plusDays(1)); // RUNTIME ERROR: UnsupportedTemporalTypeException!

4. DateTimeFormatter Parsing and Formatting

DateTimeFormatter in java.time.format provides thread-safe formatting and parsing.

Common Pattern Letters

  • y / yyyy: Year (e.g., 2026)
  • M / MM: Month as number (9, 09)
  • MMM / MMMM: Month name (Sep, September)
  • d / dd: Day of month (2, 02)
  • H / HH: Hour of day in 24-hour format (0-23)
  • h / hh: Hour in 12-hour format (1-12) with a (am/pm)
  • m / mm: Minute (00-59)
  • s / ss: Second (00-59)
  • z / zzzz: Time zone name (e.g., EDT, Eastern Daylight Time)
  • Z / XXXXX: Time zone offset (e.g., -0400, -04:00)
LocalDate date = LocalDate.of(2026, 9, 2);
LocalTime time = LocalTime.of(14, 30, 0);
LocalDateTime dateTime = LocalDateTime.of(date, time);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
System.out.println(dateTime.format(formatter)); // "09/02/2026 14:30"

// Parsing
LocalDate parsedDate = LocalDate.parse("2026-09-02", DateTimeFormatter.ISO_LOCAL_DATE);

[!IMPORTANT] Missing Temporal Field Trap: If you attempt to format a temporal object using a pattern requiring fields the object does not have (e.g., formatting a LocalDate with pattern "yyyy-MM-dd HH:mm"), a runtime UnsupportedTemporalTypeException is thrown.


5. Daylight Saving Time (DST) Transitions

When calculating time across DST boundaries with ZonedDateTime, Java automatically adjusts the wall clock or UTC offset:

1. Spring Forward Transition (Skipped Hour)

In March (US Eastern Time), wall-clock time jumps from 01:59:59 directly to 03:00:00. The hour 02:00 to 02:59 does not exist.

  • Creating ZonedDateTime.of(LocalDate.of(2026, 3, 8), LocalTime.of(2, 30), ZoneId.of("America/New_York")) automatically adjusts forward to 03:30:00-04:00.

2. Fall Back Transition (Repeated Hour)

In November (US Eastern Time), wall-clock time transitions from daylight time (-04:00) to standard time (-05:00), repeating the hour from 01:00 to 01:59.

3. Period vs. Duration on DST Transitions

  • Adding a Period (e.g., Period.ofDays(1)): Adds one conceptual calendar day, preserving local wall-clock time regardless of whether the day has 23 or 25 actual hours.
  • Adding a Duration (e.g., Duration.ofDays(1) or Duration.ofHours(24)): Adds exactly 24 elapsed hours, which may shift the local wall-clock time by 1 hour across a DST transition.
ZoneId ny = ZoneId.of("America/New_York");
// Spring transition day: March 8, 2026 (23-hour day)
ZonedDateTime before = ZonedDateTime.of(LocalDate.of(2026, 3, 7), LocalTime.of(10, 0), ny);

ZonedDateTime addPeriod = before.plus(Period.ofDays(1));
System.out.println(addPeriod); // 2026-03-08T10:00-04:00[America/New_York] (Wall clock unchanged)

ZonedDateTime addDuration = before.plus(Duration.ofDays(1));
System.out.println(addDuration); // 2026-03-08T11:00-04:00[America/New_York] (Exact 24h shifts clock!)
Loading diagram...
java.time Type Compatibility Matrix
Test Your Knowledge

What is the output of the following Java program? import java.time.*; public class DateCalc { public static void main(String[] args) { LocalDate date = LocalDate.of(2026, Month.MAY, 10); Period period = Period.ofYears(2).ofMonths(3).ofDays(5); date.plus(period); date = date.plusDays(2); System.out.println(date); } }

A
B
C
D
Test Your Knowledge

What happens when executing the following code snippet? LocalDate ld = LocalDate.of(2026, 9, 2); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); String formatted = ld.format(dtf); System.out.println(formatted);

A
B
C
D
Test Your Knowledge

In the United States, Eastern Daylight Time (EDT) begins on Sunday, March 8, 2026, when local clocks skip from 02:00 to 03:00 (a 23-hour day). Consider this code: ZoneId zone = ZoneId.of("America/New_York"); ZonedDateTime start = ZonedDateTime.of(LocalDate.of(2026, 3, 7), LocalTime.of(9, 0), zone); ZonedDateTime pDay = start.plus(Period.ofDays(1)); ZonedDateTime dDay = start.plus(Duration.ofDays(1)); System.out.println(pDay.getHour() + " " + dDay.getHour());

A
B
C
D
Test Your Knowledge

Which of the following operations between temporal objects will execute successfully without throwing an exception?

A
B
C
D