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
// 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
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
// 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
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
// 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
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
// 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
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
// 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
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.
// 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.
// 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);
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
// 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
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
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:
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
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
// 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.)
0 Comments