What happens when you call Duration.between() on two LocalDate values, and what should you use instead?
answer
- Duration.between on LocalDate → UnsupportedTemporalTypeException: Unsupported unit: Seconds
- LocalDate has no time-of-day → no seconds to measure
- Period.between → years/months/days breakdown
- ChronoUnit.DAYS.between → single long count
- Duration.between needs time-carrying temporals (LocalDateTime/Instant/LocalTime)
basics
~10 sIt throws an exception (UnsupportedTemporalTypeException) because a LocalDate has no time-of-day, and Duration needs seconds. Use Period.between() for years/months/days, or ChronoUnit.DAYS.between() to get a number of days.
solid answer
~40 sDuration.between expects temporals that support the SECONDS field; a LocalDate is a pure date with no time component, so calling Duration.between(date1, date2) throws UnsupportedTemporalTypeException: Unsupported unit: Seconds. To measure the gap between two dates, you have two correct options. Period.between(start, end) gives a calendar breakdown — years, months, and days — which is right for human-readable offsets. ChronoUnit.DAYS.between(start, end) (or WEEKS, MONTHS, YEARS) gives a single long count in that one unit, which is right when you want a plain number like 'how many days apart.' Duration.between only works when both arguments carry a time component, e.g. two LocalDateTime, Instant, or LocalTime values. A common fix when you actually have datetimes is to keep them as LocalDateTime/Instant rather than truncating to LocalDate.
code
java · 8 linesLocalDate start = LocalDate.of(2026, 1, 15);
LocalDate end = LocalDate.of(2026, 3, 20);
// Duration.between(start, end); // throws UnsupportedTemporalTypeException: Unsupported unit: Seconds
Period p = Period.between(start, end); // P0Y2M5D (calendar breakdown)
long days = ChronoUnit.DAYS.between(start, end);// 64 (single total count)
long months = ChronoUnit.MONTHS.between(start, end); // 2 (whole months, truncated)go deeper
Knows Duration.between on dates fails and that Period.between or ChronoUnit.DAYS.between is the fix.
Names the exact exception, explains it's because LocalDate lacks a time component, and chooses Period vs ChronoUnit by whether they want a breakdown or a single count.
Explains it's an unchecked runtime exception (compiles fine), that ChronoUnit truncates, and recommends not truncating datetimes to dates when exact elapsed time is needed.
Can reason about the supported-unit model underlying all temporal arithmetic, and guides API/domain design so callers can't accidentally pick the wrong amount type for the wrong temporal.
## Setup: what `between` needs The `java.time` API models points in time (`LocalDate`, `LocalTime`, `LocalDateTime`, `Instant`, …) as **temporals** that expose a set of supported **fields/units** (the things in `ChronoField`/`ChronoUnit`). Operations that compute an *amount* between two temporals require both temporals to support the unit that amount is expressed in. - A `LocalDate` (e.g. `2026-06-20`) supports date units: DAYS, MONTHS, YEARS… It has **no** hours, minutes, or seconds. - A `LocalTime`/`LocalDateTime`/`Instant` supports time units down to nanoseconds. ## Why `Duration.between(localDate, localDate)` throws `Duration` is measured in **seconds + nanoseconds**. `Duration.between(a, b)` internally asks the temporals for their SECONDS/NANOS. A `LocalDate` cannot answer that — it has no time-of-day — so the JVM throws: ``` java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds ``` This is a **runtime** exception (unchecked), not a compile error, which is why it surprises people: the code compiles fine because `LocalDate` is a `Temporal`, but it fails at execution. ## The two correct alternatives ### 1. `Period.between(startDate, endDate)` Returns a `Period` — a **calendar breakdown** into years, months, and days. Example: from `2026-01-15` to `2026-03-20` you get `P0Y2M5D` (0 years, 2 months, 5 days). Use this when you want a human-style "2 months and 5 days." Note `Period.between` is **not** symmetric in magnitude the way subtraction is — reversing the arguments gives a negative period, and the year/month/day split depends on the calendar between the two dates. ### 2. `ChronoUnit.<UNIT>.between(start, end)` Returns a single `long` in one chosen unit: ```java long days = ChronoUnit.DAYS.between(start, end); // total whole days long months = ChronoUnit.MONTHS.between(start, end); // total whole months long years = ChronoUnit.YEARS.between(start, end); ``` This is what you want for "how many days between two dates" — a flat number, truncated toward zero (whole units only; partial units are dropped). `ChronoUnit` works on any temporals that support the unit, so `ChronoUnit.DAYS.between(localDate1, localDate2)` is valid, whereas `Duration.between` is not. ## When `Duration.between` *is* correct When both arguments carry a time component: ```java Duration d = Duration.between( LocalDateTime.of(2026, 6, 20, 9, 0), LocalDateTime.of(2026, 6, 20, 17, 30)); // d = PT8H30M ``` or between two `Instant`s, or two `LocalTime`s. ## Practical guidance - Want a calendar offset (Y/M/D) → `Period.between`. - Want one number in a single unit (days, weeks, months) → `ChronoUnit.<UNIT>.between`. - Want exact elapsed time → make sure you have time-carrying temporals, then `Duration.between`. - If you 'lost' the time by truncating to `LocalDate`, the real fix is often to not truncate.
- What does ChronoUnit.MONTHS.between return for 2026-01-31 to 2026-03-01?It returns 1 — only whole months are counted (Jan 31 → Feb 28/29 is not yet a full month into March; from Jan 31, one whole month reaches Feb 28, then the extra days to Mar 1 don't complete a second month), so partial units are truncated.
- How would you get the precise hours between two LocalDate values at midnight?Convert each to a LocalDateTime via atStartOfDay() (ideally with a zone for DST correctness) and call Duration.between on the resulting datetimes, or use ChronoUnit.HOURS.between on the datetimes.
saying these in an interview costs you the question
- Saying it returns 0 or null instead of throwing
- Thinking it's a compile error (it's a runtime UnsupportedTemporalTypeException)
- Using Period.between when you actually want a flat day count (Period splits into Y/M/D)
- Assuming ChronoUnit.between rounds — it truncates to whole units