12. Date and Time in Java
Table of Contents
- 12.1 Date and Time
- 12.2 withXxx Methods
- 12.3 Conversion and at Methods Linking Date Time and Zone
- 12.4 Period Duration and Instant
- 12.5 Period — Human Date Amounts
- 12.6 Duration — Machine Time Amounts
- 12.7 Instant — Point on the UTC Timeline
- 12.8 Summary Table Period vs Duration vs Instant
- 12.9 TemporalUnit and TemporalAmount
12.1 Date and Time
Java provides a modern, consistent, immutable date/time API in the package java.time.*.
This API replaces the old java.util.Date and java.util.Calendar classes.
Depending on the level of detail required, Java offers four main classes:
LocalDate→ represents a date only (year–month–day)LocalTime→ represents a time only (hour–minute–second–nanosecond)LocalDateTime→ combines date + time, but no time zoneZonedDateTime→ full date + time + offset + time zone
Note
- A time zone defines rules such as daylight saving changes (for example,
Europe/Paris). - A zone offset is a fixed shift from UTC/GMT (for example,
+01:00,-07:00). - To compare two instants from different time zones, convert them to UTC (GMT) by applying the offset.
Getting the Current Date/Time
You can retrieve the current system values using the static now() methods:
System.out.println(LocalDate.now());
System.out.println(LocalTime.now());
System.out.println(LocalDateTime.now());
System.out.println(ZonedDateTime.now());
- Example output (your system may differ):
2025-12-01
19:11:53.213856300
2025-12-01T19:11:53.213856300
2025-12-01T19:11:53.214856900+01:00[Europe/Paris]
- Example: converting
ZonedDateTimeto GMT (UTC)
// Conceptual examples (not real code, just illustrating offsets):
// 2024-07-01T12:00+09:00[Asia/Tokyo] ---> 12:00 minus 9 hours ---> 03:00 UTC
// 2024-07-01T20:00-07:00[America/Los_Angeles] ---> 20:00 plus 7 hours ---> 03:00 UTC
Both represent the same instant in time, simply expressed in different time zones.
12.1.1 Creating Specific Dates and Times
You can build precise date/time objects using the of() factory methods.
All classes include multiple overloaded versions of of() (only the most common are listed here).
LocalDate — overloaded of() forms
of(int year, int month, int dayOfMonth)of(int year, Month month, int dayOfMonth)
LocalTime — overloaded of() forms
of(int hour, int minute)of(int hour, int minute, int second)of(int hour, int minute, int second, int nanoOfSecond)
LocalDateTime — overloaded of() forms
of(int year, int month, int day, int hour, int minute)of(int year, int month, int day, int hour, int minute, int second)of(int year, int month, int day, int hour, int minute, int second, int nano)of(LocalDate date, LocalTime time)
ZonedDateTime — overloaded of() forms
of(LocalDate date, LocalTime time, ZoneId zone)-
of(int y, int m, int d, int h, int min, int s, int nano, ZoneId zone) -
Examples
// Creating specific dates
var localDate1 = LocalDate.of(2025, 7, 31);
var localDate2 = LocalDate.of(2025, Month.JULY, 31);
// Creating specific times
var localTime1 = LocalTime.of(13, 21);
System.out.println(localTime1); // 13:21
System.out.println(LocalTime.of(13, 21, 52)); // 13:21:52
System.out.println(LocalTime.of(13, 21, 52, 200)); // 13:21:52.000000200
// Creating LocalDateTime
var localDateTime1 = LocalDateTime.of(2025, 7, 31, 13, 55, 22);
var localDateTime2 = LocalDateTime.of(localDate1, localTime1);
// Creating a ZonedDateTime
var zoned = ZonedDateTime.of(2025, 7, 31, 13, 55, 22, 0, ZoneId.of("Europe/Paris"));
12.1.2 Date and Time Arithmetic: plus and minus Methods
All classes in the java.time package (such as LocalDate, LocalTime, LocalDateTime, ZonedDateTime, etc.) are immutable.
This means that methods like plusXxx() and minusXxx() never modify the original object — instead, they return a new instance with the adjusted value.
12.1.3 Common Patterns
Most date/time classes support three kinds of arithmetic methods:
-
Type-specific shortcuts
-
plusDays(long daysToAdd) plusHours(long hoursToAdd)-
etc.
-
Generic amount-based methods
-
plus(TemporalAmount amount)→ for examplePeriod,Duration -
minus(TemporalAmount amount) -
Generic unit-based methods
-
plus(long amountToAdd, TemporalUnit unit) minus(long amountToSubtract, TemporalUnit unit)
These allow flexible and readable date/time arithmetic.
12.1.4 LocalDate Arithmetic
LocalDate represents a date only (no time, no zone).
Main plus / minus methods (overloads)
| Method | Description |
|---|---|
plusDays(long days) |
Add days |
plusWeeks(long weeks) |
Add weeks |
plusMonths(long months) |
Add months |
plusYears(long years) |
Add years |
minusDays(long days) |
Subtract days |
minusWeeks(long weeks) |
Subtract weeks |
minusMonths(long months) |
Subtract months |
minusYears(long years) |
Subtract years |
plus(TemporalAmount amount) |
Add a Period |
minus(TemporalAmount amount) |
Subtract a Period |
plus(long amountToAdd, TemporalUnit unit) |
Add using ChronoUnit (e.g., DAYS, MONTHS) |
minus(long amountToSubtract, TemporalUnit unit) |
Subtract using ChronoUnit |
- Examples:
LocalDate date = LocalDate.of(2025, 3, 10);
LocalDate d1 = date.plusDays(5); // 2025-03-15
LocalDate d2 = date.minusWeeks(2); // 2025-02-24
LocalDate d3 = date.plusMonths(1); // 2025-04-10
LocalDate d4 = date.plusYears(2); // 2027-03-10
// Using ChronoUnit
LocalDate d5 = date.plus(10, ChronoUnit.DAYS); // 2025-03-20
// Using Period
Period p = Period.of(1, 2, 3); // 1 year, 2 months, 3 days
LocalDate d6 = date.plus(p);
12.1.5 LocalTime Arithmetic
LocalTime represents time only (no date, no zone).
Main plus / minus methods (overloads)
| Method | Description |
|---|---|
plusNanos(long nanos) |
Add nanoseconds |
plusSeconds(long seconds) |
Add seconds |
plusMinutes(long minutes) |
Add minutes |
plusHours(long hours) |
Add hours |
minusNanos(long nanos) |
Subtract nanoseconds |
minusSeconds(long seconds) |
Subtract seconds |
minusMinutes(long minutes) |
Subtract minutes |
minusHours(long hours) |
Subtract hours |
plus(TemporalAmount amount) |
Add a Duration |
minus(TemporalAmount amount) |
Subtract a Duration |
plus(long amountToAdd, TemporalUnit unit) |
Add using ChronoUnit |
minus(long amountToSubtract, TemporalUnit unit) |
Subtract using ChronoUnit |
- Examples
LocalTime time = LocalTime.of(13, 30); // 13:30
LocalTime t1 = time.plusHours(2); // 15:30
LocalTime t2 = time.minusMinutes(45); // 12:45
LocalTime t3 = time.plusSeconds(90); // 13:31:30
// Using ChronoUnit
LocalTime t4 = time.plus(3, ChronoUnit.HOURS); // 16:30
// Using Duration
Duration d = Duration.ofMinutes(90);
LocalTime t5 = time.plus(d); // 15:00
Note
When time arithmetic crosses midnight, the date is ignored with LocalTime.
For example, 23:30 + 2 hours = 01:30 (with no date involved).
12.1.6 LocalDateTime Arithmetic
LocalDateTime combines date + time, but still no time zone.
It supports both the date-related and time-related shortcut methods.
Main plus / minus methods (overloads)
| Method | Description |
|---|---|
plusYears(long years) / minusYears(long years) |
Adjust years |
plusMonths(long months) / minusMonths(long months) |
Adjust months |
plusWeeks(long weeks) / minusWeeks(long weeks) |
Adjust weeks |
plusDays(long days) / minusDays(long days) |
Adjust days |
plusHours(long hours) / minusHours(long hours) |
Adjust hours |
plusMinutes(long minutes) / minusMinutes(long minutes) |
Adjust minutes |
plusSeconds(long seconds) / minusSeconds(long seconds) |
Adjust seconds |
plusNanos(long nanos) / minusNanos(long nanos) |
Adjust nanoseconds |
plus(TemporalAmount amount) / minus(TemporalAmount amount) |
Add/subtract Period or Duration |
plus(long amountToAdd, TemporalUnit unit) / minus(long amountToSubtract, TemporalUnit unit) |
Using ChronoUnit |
- Examples
LocalDateTime ldt = LocalDateTime.of(2025, 3, 10, 13, 30); // 2025-03-10T13:30
LocalDateTime l1 = ldt.plusDays(1); // 2025-03-11T13:30
LocalDateTime l2 = ldt.minusHours(3); // 2025-03-10T10:30
LocalDateTime l3 = ldt.plusMinutes(90); // 2025-03-10T15:00
// Using ChronoUnit
LocalDateTime l4 = ldt.plus(2, ChronoUnit.WEEKS); // 2025-03-24T13:30
// Using Period and Duration
Period p = Period.ofDays(10);
Duration d = Duration.ofHours(5);
LocalDateTime l5 = ldt.plus(p); // 2025-03-20T13:30
LocalDateTime l6 = ldt.plus(d); // 2025-03-10T18:30
12.1.7 ZonedDateTime Arithmetic
ZonedDateTime represents date + time + time zone + offset.
It supports the same plus/minus methods as LocalDateTime, but with extra attention to time zones and Daylight Saving Time (DST).
Main plus / minus methods (overloads)
| Method | Description |
|---|---|
plusYears(long years) / minusYears(long years) |
Adjust years |
plusMonths(long months) / minusMonths(long months) |
Adjust months |
plusWeeks(long weeks) / minusWeeks(long weeks) |
Adjust weeks |
plusDays(long days) / minusDays(long days) |
Adjust days |
plusHours(long hours) / minusHours(long hours) |
Adjust hours |
plusMinutes(long minutes) / minusMinutes(long minutes) |
Adjust minutes |
plusSeconds(long seconds) / minusSeconds(long seconds) |
Adjust seconds |
plusNanos(long nanos) / minusNanos(long nanos) |
Adjust nanoseconds |
plus(TemporalAmount amount) / minus(TemporalAmount amount) |
Period / Duration |
plus(long amountToAdd, TemporalUnit unit) / minus(long amountToSubtract, TemporalUnit unit) |
Using ChronoUnit |
- Examples (with time zones and DST):
ZonedDateTime zdt = ZonedDateTime.of(
2025, 3, 30, 1, 30, 0, 0,
ZoneId.of("Europe/Paris")
);
// Add 2 hours across a possible DST change
ZonedDateTime z1 = zdt.plusHours(2);
System.out.println(zdt);
System.out.println(z1);
Depending on Daylight Saving rules for that date:
- The local time might jump from 02:00 to 03:00 or similar.
ZonedDateTimeadjusts the offset and local time according to the zone rules, but still represents the correct instant on the timeline.
Important
For ZonedDateTime, arithmetic is defined in terms of the local timeline and time zone rules, which can cause hour shifts during DST transitions.
12.1.8 Summary Table
| Class | Shortcut plus/minus methods | Generic methods |
|---|---|---|
| LocalDate | plusDays, plusWeeks, plusMonths, plusYears (and minus) | plus/minus(TemporalAmount), plus/minus(long, TemporalUnit) |
| LocalTime | plusNanos, plusSeconds, plusMinutes, plusHours (and minus) | plus/minus(TemporalAmount), plus/minus(long, TemporalUnit) |
| LocalDateTime | All LocalDate + LocalTime shortcuts | plus/minus(TemporalAmount), plus/minus(long, TemporalUnit) |
| ZonedDateTime | Same as LocalDateTime, but zone-aware | plus/minus(TemporalAmount), plus/minus(long, TemporalUnit) |
12.2 withXxx(...) Methods
The with... methods return a copy of the object with one field changed.
They never mutate the original instance.
| Class | Common with... methods (not exhaustive) | Description |
|---|---|---|
LocalDate |
withYear(int year) | Same date, but with a different year |
| LocalDate.withMonth(int month) | Same date, different month (1–12) | |
| LocalDate.withDayOfMonth(int dayOfMonth) | Same date, different day of month | |
| LocalDate.with(TemporalField field, long newValue) | Generic field-based adjustment | |
| LocalDate.with(TemporalAdjuster adjuster) | Uses an adjuster (e.g. firstDayOfMonth()) | |
LocalTime |
withHour(int hour) | Same time, different hour |
| LocalTime.withMinute(int minute) | Same time, different minute | |
| LocalTime.withSecond(int second) | Same time, different second | |
| LocalTime.withNano(int nanoOfSecond) | Same time, different nanosecond | |
| LocalTime.with(TemporalField field, long newValue) | Generic field-based adjustment | |
| LocalTime.with(TemporalAdjuster adjuster) | Adjust using a temporal adjuster | |
LocalDateTime |
withYear(int year), withMonth(int month), withDayOfMonth(int day) | Change date part only |
| withHour(int hour), withMinute(int minute), withSecond(int second) | Change time part only | |
| withNano(int nanoOfSecond) | Change nanosecond | |
| with(TemporalField field, long newValue) | Generic field-based adjustment | |
| with(TemporalAdjuster adjuster) | Adjust using a temporal adjuster | |
ZonedDateTime |
all the withXxx(...) of LocalDateTime | Change local date/time components |
| withZoneSameInstant(ZoneId zone) | Same instant, different zone (changes local time) | |
| withZoneSameLocal(ZoneId zone) | Same local date/time, different zone (changes instant) |
12.3 Conversion & at... Methods (Linking Date, Time, and Zone)
These methods are used to combine or convert between LocalDate, LocalTime, LocalDateTime, and ZonedDateTime.
| From | Method | Result | Description |
|---|---|---|---|
LocalDate |
atTime(LocalTime time) |
LocalDateTime | Combines this date with a given time |
| LocalDate | atTime(int hour, int minute) |
LocalDateTime | Convenience overloads with numeric time components |
| LocalDate | atTime(int hour, int minute, int second) |
LocalDateTime | — |
| LocalDate | atTime(int hour, int minute, int second, int nano) |
LocalDateTime | — |
| LocalDate | atStartOfDay() |
LocalDateTime | This date at time 00:00 |
| LocalDate | atStartOfDay(ZoneId zone) |
ZonedDateTime | This date at start of day in a specific zone |
LocalTime |
atDate(LocalDate date) |
LocalDateTime | Combines this time with a given date |
LocalDateTime |
atZone(ZoneId zone) |
ZonedDateTime | Adds a time zone to a local date-time |
| LocalDateTime | toLocalDate() |
LocalDate | Extracts the date component |
| LocalDateTime | toLocalTime() |
LocalTime | Extracts the time component |
ZonedDateTime |
toLocalDate() |
LocalDate | Drops zone/offset, keeps local date |
| ZonedDateTime | toLocalTime() |
LocalTime | Drops zone/offset, keeps local time |
| ZonedDateTime | toLocalDateTime() |
LocalDateTime | Drops zone/offset, keeps local date-time |
12.4 Period, Duration, and Instant
The java.time package provides three essential temporal classes that represent amounts of time or points on the timeline:
- Period → human-based date amounts (years, months, days)
- Duration → machine-based time amounts (seconds, nanoseconds)
- Instant → a point on the UTC timeline
12.5 Period — Human Date Amounts
Period represents a date-based amount of time, such as “3 years, 2 months, and 5 days”.
It is used with LocalDate and LocalDateTime (because they contain date parts).
Creation Methods
| Method | Description |
|---|---|
| Period.ofYears(int years) | Only years |
| Period.ofMonths(int months) | Only months |
| Period.ofWeeks(int weeks) | Converts weeks to days |
| Period.ofDays(int days) | Only days |
| Period.of(int years, int months, int days) | Full period |
| Period.parse(CharSequence text) | ISO-8601 format: "P1Y2M3D", "P7D", "P1W", ... |
Key properties
- Does not support hours, minutes, seconds, nanoseconds.
- Can be negative.
-
Immutable.
-
Examples
Period p1 = Period.ofYears(1); // P1Y
Period p2 = Period.of(1, 2, 3); // P1Y2M3D
Period p3 = Period.ofWeeks(2); // P14D (converted to days)
LocalDate base = LocalDate.of(2025, 1, 10);
LocalDate result = base.plus(p2); // 2026-03-13
Note
Period.parse("P1W") is allowed and represents a period of 7 days (equivalent to "P7D").
Tip
Period is calendar-based: adding a period of months/years respects month lengths and leap years.
12.6 Duration — Machine Time Amounts
Duration represents a time-based amount in seconds and nanoseconds.
It is used with LocalTime, LocalDateTime, ZonedDateTime, and Instant.
Creation Methods
| Method | Description |
|---|---|
| Duration.ofDays(long days) | Converts days to seconds |
| Duration.ofHours(long hours) | Converts hours to seconds |
| Duration.ofMinutes(long minutes) | Converts minutes to seconds |
| Duration.ofSeconds(long seconds) | Base representation in seconds |
| Duration.ofSeconds(long seconds, long nanoAdjustment) | Seconds plus additional nanos |
| Duration.ofMillis(long millis) | Converts milliseconds to nanos |
| Duration.ofNanos(long nanos) | Nanoseconds only |
| Duration.between(Temporal start, Temporal end) | Compute duration between two instants |
| Duration.parse(CharSequence text) | ISO: "PT20H", "PT15M", "PT10S" |
Key characteristics
- Supports hours down to nanoseconds, but not years/months/weeks directly.
- Ideal for machine-level time computations.
-
Immutable.
-
Examples
Duration d1 = Duration.ofHours(5); // PT5H
Duration d2 = Duration.ofMinutes(90); // PT1H30M
LocalTime t = LocalTime.of(10, 0);
LocalTime t2 = t.plus(d2); // 11:30
ZonedDateTime z1 = ZonedDateTime.of(
2024, 3, 30, 1, 0, 0, 0,
ZoneId.of("Europe/Paris")
);
ZonedDateTime z2 = z1.plusHours(2); // DST-aware
ZonedDateTime z3 = z1.plus(d2); // Duration-based
Note
Duration.ofDays(1) represents exactly 24 hours of machine time. In a zone with DST, 24 hours may not align with “the same local time tomorrow”.
12.7 Instant — Point on the UTC Timeline
Instant represents a single moment in time relative to UTC, with nanosecond precision.
It contains:
- Seconds since the epoch (1970-01-01T00:00Z).
- A nanoseconds adjustment.
Creation Methods
| Method | Description |
|---|---|
| Instant.now() | Current moment in UTC |
| Instant.ofEpochSecond(long seconds) | From epoch seconds |
| Instant.ofEpochSecond(long seconds, long nanos) | From seconds plus nanos |
| Instant.ofEpochMilli(long millis) | From epoch milliseconds |
| Instant.parse(CharSequence text) | ISO: "2024-01-01T10:15:30Z" |
Conversions
| Action | Method |
|---|---|
| Instant → zoned time | instant.atZone(zoneId) |
| ZonedDateTime → Instant | zdt.toInstant() |
| LocalDateTime → Instant | Not allowed directly (needs a zone) |
- Example
Instant i = Instant.now();
ZonedDateTime z = i.atZone(ZoneId.of("Europe/Paris"));
Instant back = z.toInstant(); // same moment
// Duration between instants
Instant start = Instant.parse("2024-01-01T10:00:00Z");
Instant end = Instant.parse("2024-01-01T12:30:00Z");
Duration between = Duration.between(start, end); // PT2H30M
Important
Instant is always UTC, with no time zone information attached. It cannot be combined with a Period; use Duration instead.
12.8 Summary Table (Period vs Duration vs Instant)
| Concept | Represents | Good For | Works With | Notes |
|---|---|---|---|---|
| Period | Years, months, days | Calendar arithmetic | LocalDate, LocalDateTime | Human-based units |
| Duration | Hours to nanoseconds | Precise time calculations | LocalTime, LocalDateTime, ZonedDateTime, Instant | Machine-based |
| Instant | Exact point on UTC timeline | Timestamp representation | Convertible to/from ZonedDateTime | Cannot combine with Period |
Common Traps
Period.of(1, 0, 0)is not the same asDuration.ofDays(365)(leap years!).Duration.ofDays(1)may not equal a full “calendar day” in a DST zone.LocalDateTimecannot be converted to anInstantwithout a time zone.Period.parse("P1W")is valid and results in a period of 7 days.
12.9 TemporalUnit and TemporalAmount
The java.time API is built on two key interfaces that define how dates, times, and durations are manipulated:
TemporalUnit→ represents a unit of time (for example, DAYS, HOURS, MINUTES).TemporalAmount→ represents an amount of time (for example,Period,Duration).
Both are essential for understanding how the plus, minus, and with methods work.
12.9.1 TemporalUnit
TemporalUnit represents a single unit of date/time measurement.
The main implementation used in Java is:
12.9.2 ChronoUnit enum
This enum provides the standard units used in the ISO-8601 chronology:
| Category | Units |
|---|---|
| Date units | DAYS, WEEKS, MONTHS, YEARS, DECADES, CENTURIES, MILLENNIA, ERAS |
| Time units | NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS |
| Special | FOREVER |
A TemporalUnit can be used directly with plus() and minus() methods.
- Examples using
ChronoUnit:
LocalDate date = LocalDate.of(2025, 3, 10);
LocalDate d1 = date.plus(10, ChronoUnit.DAYS); // 2025-03-20
LocalDate d2 = date.minus(2, ChronoUnit.MONTHS); // 2025-01-10
LocalTime time = LocalTime.of(10, 0);
LocalTime t1 = time.plus(90, ChronoUnit.MINUTES); // 11:30
Important
You cannot use time-based units with LocalDate, nor date-based units with LocalTime.
- Examples:
// ❌ UnsupportedTemporalTypeException
LocalDate d = LocalDate.now().plus(5, ChronoUnit.HOURS);
// ❌ UnsupportedTemporalTypeException
LocalTime t = LocalTime.now().plus(1, ChronoUnit.DAYS);
12.9.3 TemporalAmount
TemporalAmount represents a multiple-unit amount of time (for example, “2 years, 3 months”, or “90 minutes”).
It is implemented by:
Period→ years, months, days (date-based)Duration→ seconds, nanoseconds (time-based)
Both can be passed to date/time objects to adjust them using plus() and minus().
12.9.4 Period as a TemporalAmount
Period represents a human-based amount: years, months, days.
- Examples:
Period p = Period.of(1, 2, 3); // 1 year, 2 months, 3 days
LocalDate base = LocalDate.of(2025, 3, 10);
LocalDate result = base.plus(p); // 2026-05-13
Notes
Periodcannot be used withLocalTime(no date component).Period.ofWeeks(n)is converted internally to days (n × 7).
12.9.5 Duration as a TemporalAmount
Duration represents machine-based time: seconds + nanoseconds.
- Examples:
Duration d = Duration.ofHours(5).plusMinutes(30); // PT5H30M
LocalDateTime ldt = LocalDateTime.of(2025, 3, 10, 10, 0);
LocalDateTime result = ldt.plus(d); // 2025-03-10T15:30
Notes
Durationcan be used with classes that have time components (LocalTime,LocalDateTime,ZonedDateTime,Instant).Durationcannot be applied toLocalDate→ it will throwUnsupportedTemporalTypeException.Durationinteracts with zones and DST transitions when applied toZonedDateTime.
12.9.6 Using TemporalAmount vs TemporalUnit
Using a TemporalUnit:
LocalDate d1 = LocalDate.now().plus(5, ChronoUnit.DAYS);
Using a TemporalAmount:
Period p = Period.ofDays(5);
LocalDate d2 = LocalDate.now().plus(p);
Both produce the same result when supported.
Differences
| Aspect | TemporalUnit | TemporalAmount |
|---|---|---|
| Represents | A single unit (e.g., DAYS) | A structured quantity (e.g. 2Y, 5M, 3D) |
| Examples | ChronoUnit.DAYS | Period.of(2,5,3) |
| Supports multiple fields | No | Yes |
| Good for | Simple increments | Complex increments |
| Common with | All date/time classes | Restricted by type |
12.9.7 between(...) Methods
Many classes provide a between method from ChronoUnit, Duration, or Period.
Using Duration.between (for time-based classes)
Duration d = Duration.between(
LocalTime.of(10, 0),
LocalTime.of(13, 30)
);
// PT3H30M
Using Period.between (only for dates)
Period p = Period.between(
LocalDate.of(2025, 3, 1),
LocalDate.of(2025, 5, 10)
);
// P2M9D
Using ChronoUnit between
long days = ChronoUnit.DAYS.between(
LocalDate.of(2025, 3, 1),
LocalDate.of(2025, 3, 10)
);
// 9
Important
ChronoUnit.between(...) always returns a long,
while Period.between returns a Period,
and Duration.between returns a Duration.
12.9.8 Common Pitfalls
- Applying the wrong
TemporalAmount:
// LocalTime.plus(Period.ofDays(1)) // ❌ compile-time error
// LocalDate.plus(Duration.ofHours(1)) // ❌ runtime error: UnsupportedTemporalTypeException
- DST changes with Duration: adding 24 hours is not always “tomorrow” in a zone with DST changes.
Period.ofWeeks(1)is exactly 7 days; DST effects show up when applied to zone-aware types.Instant.plus(Period)→ runtimeUnsupportedTemporalTypeException; useDurationinstead.Instantcannot be created directly from aLocalDateTime; you must first apply a time zone:ldt.atZone(zone).toInstant().
12.9.9 Summary
| Feature | TemporalUnit | TemporalAmount | ChronoUnit | Period | Duration |
|---|---|---|---|---|---|
| Represents | A unit | An amount | enum of units | Y/M/D | S + nanos |
| Multi-field | No | Yes | No | Yes | No |
| Works with | plus/minus | plus/minus | date/time | LocalDate/LocalDateTime | Time/time-zone |
| Human-based | No | Yes | No | Yes | No |
| Machine-based | Yes | Yes | Yes | No | Yes |