Date-Time API and Time Zones in Java

Master the Java Date-Time API (java.time package) including LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Duration, Period, Instant, time zones, and daylight saving time for the OCP 21 exam.

Table of Contents

1. Date-Time API Overview

The Java Date-Time API (introduced in Java 8) provides a comprehensive model for date and time manipulation. It replaces the old java.util.Date and java.util.Calendar classes.

1.1 Key Features

  • Immutable: All date-time classes are immutable and thread-safe
  • Clear API: Methods have clear, descriptive names
  • Time Zone Support: Built-in support for time zones and DST
  • Fluent API: Methods can be chained for readability
  • Precision: Supports nanoseconds precision

1.2 Main Classes

Class Description
LocalDate Date without time (year-month-day)
LocalTime Time without date (hour-minute-second-nano)
LocalDateTime Date and time without time zone
ZonedDateTime Date and time with time zone
Instant Point in time on UTC timeline
Duration Time-based amount (seconds, nanoseconds)
Period Date-based amount (years, months, days)

2. LocalDate

LocalDate represents a date without time or time zone information (year-month-day).

2.1 Creating LocalDate

Example:
// Current date
LocalDate today = LocalDate.now();

// Specific date
LocalDate date1 = LocalDate.of(2024, 1, 15);
LocalDate date2 = LocalDate.of(2024, Month.JANUARY, 15);

// Parsing from string (ISO format: yyyy-MM-dd)
LocalDate date3 = LocalDate.parse("2024-01-15");

// Using Year, Month, Day
LocalDate date4 = LocalDate.of(2024, 1, 15);

2.2 LocalDate Methods

Example:
LocalDate date = LocalDate.of(2024, 1, 15);

// Getting components
int year = date.getYear();              // 2024
int month = date.getMonthValue();       // 1
Month monthEnum = date.getMonth();      // JANUARY
int day = date.getDayOfMonth();        // 15
DayOfWeek dayOfWeek = date.getDayOfWeek(); // MONDAY
int dayOfYear = date.getDayOfYear();   // 15

// Modifying (returns new object)
LocalDate nextWeek = date.plusWeeks(1);      // 2024-01-22
LocalDate nextMonth = date.plusMonths(1);    // 2024-02-15
LocalDate nextYear = date.plusYears(1);      // 2025-01-15
LocalDate previousDay = date.minusDays(1);   // 2024-01-14

// Comparing
boolean isAfter = date.isAfter(LocalDate.now());
boolean isBefore = date.isBefore(LocalDate.now());
boolean isEqual = date.isEqual(LocalDate.now());

3. LocalTime

LocalTime represents a time without date or time zone information (hour-minute-second-nanosecond).

3.1 Creating LocalTime

Example:
// Current time
LocalTime now = LocalTime.now();

// Specific time
LocalTime time1 = LocalTime.of(14, 30);           // 14:30:00
LocalTime time2 = LocalTime.of(14, 30, 45);       // 14:30:45
LocalTime time3 = LocalTime.of(14, 30, 45, 123);   // 14:30:45.000000123

// Parsing from string (ISO format: HH:mm:ss)
LocalTime time4 = LocalTime.parse("14:30:45");

// Constants
LocalTime midnight = LocalTime.MIDNIGHT;  // 00:00:00
LocalTime noon = LocalTime.NOON;          // 12:00:00

3.2 LocalTime Methods

Example:
LocalTime time = LocalTime.of(14, 30, 45);

// Getting components
int hour = time.getHour();        // 14
int minute = time.getMinute();    // 30
int second = time.getSecond();     // 45
int nano = time.getNano();        // 0

// Modifying
LocalTime later = time.plusHours(2);      // 16:30:45
LocalTime earlier = time.minusMinutes(30); // 14:00:45
LocalTime withHour = time.withHour(10);   // 10:30:45

// Comparing
boolean isAfter = time.isAfter(LocalTime.NOON);
boolean isBefore = time.isBefore(LocalTime.NOON);

4. LocalDateTime

LocalDateTime represents a date-time without time zone information. It combines LocalDate and LocalTime.

4.1 Creating LocalDateTime

Example:
// Current date-time
LocalDateTime now = LocalDateTime.now();

// Specific date-time
LocalDateTime dt1 = LocalDateTime.of(2024, 1, 15, 14, 30);
LocalDateTime dt2 = LocalDateTime.of(2024, Month.JANUARY, 15, 14, 30, 45);

// From LocalDate and LocalTime
LocalDate date = LocalDate.of(2024, 1, 15);
LocalTime time = LocalTime.of(14, 30);
LocalDateTime dt3 = LocalDateTime.of(date, time);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);

// Parsing from string (ISO format: yyyy-MM-ddTHH:mm:ss)
LocalDateTime dt6 = LocalDateTime.parse("2024-01-15T14:30:45");

4.2 LocalDateTime Methods

Example:
LocalDateTime dt = LocalDateTime.of(2024, 1, 15, 14, 30);

// Getting components
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
int year = dt.getYear();
int hour = dt.getHour();

// Modifying
LocalDateTime nextHour = dt.plusHours(1);
LocalDateTime nextDay = dt.plusDays(1);
LocalDateTime withYear = dt.withYear(2025);

// Converting to other types
ZonedDateTime zoned = dt.atZone(ZoneId.of("America/New_York"));
Instant instant = dt.toInstant(ZoneOffset.UTC);

5. ZonedDateTime

ZonedDateTime represents a date-time with time zone information. It handles daylight saving time automatically.

5.1 Creating ZonedDateTime

Example:
// Current date-time in system default time zone
ZonedDateTime now = ZonedDateTime.now();

// Specific time zone
ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime zdt1 = ZonedDateTime.now(zoneId);

// From LocalDateTime with time zone
LocalDateTime ldt = LocalDateTime.of(2024, 1, 15, 14, 30);
ZonedDateTime zdt2 = ldt.atZone(zoneId);

// Specific date-time in time zone
ZonedDateTime zdt3 = ZonedDateTime.of(2024, 1, 15, 14, 30, 0, 0, zoneId);

// Parsing
ZonedDateTime zdt4 = ZonedDateTime.parse("2024-01-15T14:30:00-05:00[America/New_York]");

5.2 ZonedDateTime Methods

Example:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("America/New_York"));

// Getting components
ZoneId zone = zdt.getZone();
LocalDateTime ldt = zdt.toLocalDateTime();
LocalDate date = zdt.toLocalDate();
LocalTime time = zdt.toLocalTime();
ZoneOffset offset = zdt.getOffset();

// Converting to other time zones
ZonedDateTime tokyo = zdt.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
ZonedDateTime utc = zdt.withZoneSameInstant(ZoneOffset.UTC);

// Converting to Instant
Instant instant = zdt.toInstant();

6. Instant

Instant represents a point in time on the UTC timeline. It's useful for timestamps and machine-readable time.

6.1 Creating Instant

Example:
// Current instant
Instant now = Instant.now();

// From epoch seconds
Instant epoch = Instant.ofEpochSecond(1609459200);  // 2021-01-01 00:00:00 UTC

// From epoch seconds and nanoseconds
Instant instant = Instant.ofEpochSecond(1609459200, 500000000);

// From epoch milliseconds
Instant fromMillis = Instant.ofEpochMilli(1609459200000L);

// Parsing from string (ISO-8601 format)
Instant parsed = Instant.parse("2024-01-15T14:30:00Z");

6.2 Instant Methods

Example:
Instant instant = Instant.now();

// Getting epoch values
long epochSeconds = instant.getEpochSecond();
long epochMillis = instant.toEpochMilli();
int nano = instant.getNano();

// Modifying
Instant plusSeconds = instant.plusSeconds(3600);
Instant minusMinutes = instant.minus(1, ChronoUnit.MINUTES);

// Converting to/from other types
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/New_York"));
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

7. Duration and Period

7.1 Duration

Duration represents a time-based amount (hours, minutes, seconds, nanoseconds). It's used for measuring time intervals.

Example:
// Creating Duration
Duration d1 = Duration.ofHours(2);
Duration d2 = Duration.ofMinutes(30);
Duration d3 = Duration.ofSeconds(90);
Duration d4 = Duration.of(1, ChronoUnit.HOURS);

// Between two instants
Instant start = Instant.now();
// ... some operation ...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);

// Between two LocalTime
LocalTime time1 = LocalTime.of(10, 0);
LocalTime time2 = LocalTime.of(12, 30);
Duration diff = Duration.between(time1, time2);

// Getting components
long hours = d1.toHours();
long minutes = d1.toMinutes();
long seconds = d1.getSeconds();
long nanos = d1.getNano();

// Modifying
Duration doubled = d1.multipliedBy(2);
Duration half = d1.dividedBy(2);

7.2 Period

Period represents a date-based amount (years, months, days). It's used for measuring calendar intervals.

Example:
// Creating Period
Period p1 = Period.ofDays(7);
Period p2 = Period.ofWeeks(2);
Period p3 = Period.ofMonths(3);
Period p4 = Period.ofYears(1);
Period p5 = Period.of(1, 2, 3);  // 1 year, 2 months, 3 days

// Between two LocalDate
LocalDate date1 = LocalDate.of(2024, 1, 1);
LocalDate date2 = LocalDate.of(2024, 3, 15);
Period period = Period.between(date1, date2);

// Parsing
Period parsed = Period.parse("P1Y2M3D");  // 1 year, 2 months, 3 days

// Getting components
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();

// Modifying dates
LocalDate future = date1.plus(period);
LocalDate past = date2.minus(period);
Key Difference: Use Duration for time-based intervals (hours, minutes, seconds). Use Period for date-based intervals (years, months, days).

8. Time Zones

Time zones are represented by the ZoneId class. Java uses IANA Time Zone Database identifiers.

8.1 Working with ZoneId

Example:
// Getting time zones
ZoneId systemDefault = ZoneId.systemDefault();
ZoneId utc = ZoneId.of("UTC");
ZoneId newYork = ZoneId.of("America/New_York");
ZoneId tokyo = ZoneId.of("Asia/Tokyo");
ZoneId london = ZoneId.of("Europe/London");

// Available time zones
Set<String> allZones = ZoneId.getAvailableZoneIds();

// ZoneOffset (fixed offset from UTC)
ZoneOffset offset = ZoneOffset.of("+05:30");
ZoneOffset offset2 = ZoneOffset.ofHours(5);
ZoneOffset offset3 = ZoneOffset.ofHoursMinutes(5, 30);

8.2 Converting Between Time Zones

Example:
ZonedDateTime nyTime = ZonedDateTime.now(ZoneId.of("America/New_York"));

// Convert to different time zone (same instant)
ZonedDateTime tokyoTime = nyTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));

// Convert to different time zone (same local time)
ZonedDateTime sameLocal = nyTime.withZoneSameLocal(ZoneId.of("UTC"));

// From LocalDateTime to ZonedDateTime
LocalDateTime ldt = LocalDateTime.of(2024, 1, 15, 14, 30);
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));

9. Daylight Saving Time

Daylight Saving Time (DST) is automatically handled by the Date-Time API when using ZonedDateTime with proper time zone IDs.

9.1 DST Transitions

Example:
ZoneId nyZone = ZoneId.of("America/New_York");

// Spring forward (DST starts) - March 10, 2024, 2:00 AM
LocalDateTime beforeDST = LocalDateTime.of(2024, 3, 10, 1, 30);
ZonedDateTime zdt1 = beforeDST.atZone(nyZone);  // 2024-03-10T01:30:00-05:00[America/New_York]

LocalDateTime afterDST = LocalDateTime.of(2024, 3, 10, 3, 0);
ZonedDateTime zdt2 = afterDST.atZone(nyZone);   // 2024-03-10T03:00:00-04:00[America/New_York]

// Fall back (DST ends) - November 3, 2024, 2:00 AM
LocalDateTime fallBack = LocalDateTime.of(2024, 11, 3, 1, 30);
ZonedDateTime zdt3 = fallBack.atZone(nyZone);   // 2024-11-03T01:30:00-04:00[America/New_York]

// Note: 2:00 AM becomes 1:00 AM (hour repeats)

9.2 Handling Ambiguous Times

During DST transitions, some times may be ambiguous or invalid. The API handles these cases:

Example:
ZoneId nyZone = ZoneId.of("America/New_York");

// Invalid time (during spring forward)
LocalDateTime invalid = LocalDateTime.of(2024, 3, 10, 2, 30);
try {
    ZonedDateTime zdt = invalid.atZone(nyZone);
} catch (DateTimeException e) {
    // This time doesn't exist (skipped during DST transition)
}

// Ambiguous time (during fall back) - 1:30 AM occurs twice
LocalDateTime ambiguous = LocalDateTime.of(2024, 11, 3, 1, 30);
ZonedDateTime zdt1 = ambiguous.atZone(nyZone);  // Uses standard time by default
ZonedDateTime zdt2 = ambiguous.atZone(nyZone).withEarlierOffsetAtOverlap();  // Earlier offset
ZonedDateTime zdt3 = ambiguous.atZone(nyZone).withLaterOffsetAtOverlap();   // Later offset

10. Formatting and Parsing

The DateTimeFormatter class is used for formatting and parsing date-time objects.

10.1 Formatting

Example:
LocalDateTime dt = LocalDateTime.of(2024, 1, 15, 14, 30, 45);

// Predefined formatters
String iso = dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
String isoDate = dt.format(DateTimeFormatter.ISO_LOCAL_DATE);
String isoTime = dt.format(DateTimeFormatter.ISO_LOCAL_TIME);

// Custom formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dt.format(formatter);  // "2024-01-15 14:30:45"

// With locale
DateTimeFormatter localized = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy", Locale.US);
String localizedStr = dt.format(localized);  // "Monday, January 15, 2024"

10.2 Parsing

Example:
// Parsing ISO format (default)
LocalDateTime dt1 = LocalDateTime.parse("2024-01-15T14:30:45");

// Parsing with custom formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dt2 = LocalDateTime.parse("2024-01-15 14:30:45", formatter);

// Parsing ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.parse("2024-01-15T14:30:45-05:00[America/New_York]");

// Parsing with locale
DateTimeFormatter localized = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy", Locale.US);
LocalDate date = LocalDate.parse("Monday, January 15, 2024", localized);

11. Exam Key Points

Critical Concepts for OCP 21 Exam:

  • Immutability: All date-time classes are immutable; methods return new objects
  • LocalDate: Date without time (year-month-day), ISO format: yyyy-MM-dd
  • LocalTime: Time without date (hour-minute-second-nano), ISO format: HH:mm:ss
  • LocalDateTime: Combines LocalDate and LocalTime, ISO format: yyyy-MM-ddTHH:mm:ss
  • ZonedDateTime: Date-time with time zone, handles DST automatically
  • Instant: Point in time on UTC timeline, useful for timestamps
  • Duration: Time-based interval (seconds, nanoseconds) - use for hours/minutes
  • Period: Date-based interval (years, months, days) - use for calendar dates
  • ZoneId: Represents time zones using IANA identifiers (e.g., "America/New_York")
  • Daylight Saving Time: Automatically handled by ZonedDateTime
  • Parsing: Use parse() for ISO format, custom formatters for other formats
  • Formatting: Use format() with DateTimeFormatter
  • Method Chaining: Most methods return new objects, allowing chaining
  • withZoneSameInstant: Converts to different time zone at same instant
  • withZoneSameLocal: Converts to different time zone keeping same local time
  • atZone: Converts LocalDateTime to ZonedDateTime
  • toInstant: Converts ZonedDateTime to Instant
  • of() vs now(): of() creates specific date-time, now() gets current
  • plus/minus methods: Add or subtract time amounts (plusDays, minusHours, etc.)
  • with methods: Set specific components (withYear, withMonth, etc.)

Post a Comment

0 Comments