Duration vs Period in Java
Time-based vs date-based amounts.
Stopwatch vs calendar
**Duration is a stopwatch: an exact amount of time in seconds and nanoseconds ("90 minutes"). Period is a calendar amount in years, months and days** ("1 month 3 days") whose real length varies — a month is 28 to 31 days.
Duration call = Duration.ofMinutes(45);
Period trial = Period.ofDays(14);
LocalDate end = start.plus(trial);Reading ISO-8601
Both print in ISO-8601: **P starts the amount and T** separates the time part. PT1H30M = 1 hour 30 minutes; P1M3D = 1 month 3 days. Careful: **P90M means 90 *months*** — minutes always come after the T. Duration normalises minutes into hours.
Seconds to ISO
What does this print?
System.out.println(Duration.ofSeconds(3725));PT3725SPT1H2M5SP1H2M5S
Show the answer
PT1H2M5S — 3725 seconds = 1 hour, 2 minutes and 5 seconds, normalised and written after the T.
Months and days, separately
What does this print?
Period p = Period.between(
LocalDate.of(2024, 1, 10),
LocalDate.of(2024, 3, 15));
System.out.println(p);
System.out.println(p.getDays());P65D 65P2M5D 5P2M5D 65
Show the answer
P2M5D and 5. A Period stores months and days separately; **getDays() is only the days part**, not the total.
Total days: ChronoUnit
To count every day between two dates, use **ChronoUnit.DAYS.between(a, b)**. (Subtracting getDayOfYear() values breaks across years.)
long days = ChronoUnit.DAYS.between(
LocalDate.of(2024, 1, 10),
LocalDate.of(2024, 3, 15)); // 65Duration can't measure dates
Duration needs seconds, but a LocalDate has no time of day, so this throws **UnsupportedTemporalTypeException**. For dates use Period or ChronoUnit.DAYS, or convert with atStartOfDay() first.
Duration.between(
LocalDate.of(2024, 1, 1),
LocalDate.of(2024, 1, 2));
// UnsupportedTemporalTypeExceptionChoosing right on the job
Timeouts, SLAs and cache expiry are Durations. Free trials, contract terms and "age in years" are Periods. Confusing getDays() with total days is a classic bug in billing and reporting code — it passes tests until a range crosses a month.
Key takeaways
- Duration: hours, minutes, seconds — for times and Instants
- Period: years, months, days — for LocalDates
- Period.getDays() is only the days part, not the total
- ChronoUnit.DAYS.between(a, b) gives the total days
In ISO-8601, PT1M is one minute and P1M is one month — a single letter T makes a difference of roughly 43,000 times.
Practice questions
What does this print?
System.out.println(Duration.ofMinutes(90));- PT90M
- PT1H30M
- 1:30
- P90M
Check your answer
PT1H30M. Duration.toString uses ISO-8601 and normalises minutes into hours: PT1H30M. In ISO, P starts the amount and T separates the time part; P90M would mean 90 months.
What does this print?
Period p = Period.between(
LocalDate.of(2024, 1, 15),
LocalDate.of(2024, 3, 10));
System.out.println(p);
System.out.println(p.getDays());- P55D 55
- P1M24D 24
- P2M5D 5
- P1M24D 55
Check your answer
P1M24D 24. From 15 Jan to 15 Feb is 1 month; from 15 Feb to 10 Mar is 24 days (2024's February has 29 days). getDays() returns just that 24, not the 55 total days.