What is the difference between Duration and Period in java.time, and when would you use each?
answer
- Duration = seconds+nanos (machine/exact time)
- Period = years/months/days (calendar, variable length)
- Duration ↔ Instant/LocalTime; Period ↔ LocalDate
- 1 month has no fixed seconds → can't be a Duration
- Both immutable, both are TemporalAmount
basics
~10 sDuration measures an exact amount of time in seconds and nanoseconds (good for hours/minutes/seconds). Period measures an amount of dates in years, months and days. Use Duration for machine time, Period for calendar time.
solid answer
~40 sDuration and Period both represent an amount of time but on different scales. Duration is time-based: it holds a fixed number of seconds and nanoseconds, so it pairs with Instant, LocalTime, or LocalDateTime. Period is date-based: it holds years, months, and days, which are calendar concepts whose actual length varies (months have 28-31 days, years can be leap). So Period pairs with LocalDate. The practical rule: if you care about an exact elapsed quantity (a 90-minute timeout, two hours of uptime), use Duration; if you care about a calendar offset (one month later, in 3 years), use Period. They are not interchangeable because adding a Period of one month gives a different number of seconds depending on the month, while a Duration is always the same physical length.
go deeper
Knows Duration is for hours/minutes/seconds and Period is for years/months/days, and picks the right one for a simple task.
Can explain the time-based vs date-based distinction, which temporals each pairs with, and that calendar units are variable-length.
Articulates immutability, that mixing them throws UnsupportedTemporalTypeException, and the DST/end-of-month implications of choosing one over the other.
Frames the API split as a deliberate type-safety decision (no implicit lossy conversion), and can reason about domain modeling: when to persist exact instants+durations vs calendar offsets, and the correctness traps of using the wrong one in scheduling/billing systems.
## The problem these types solve Java 8 introduced the `java.time` package (sometimes called JSR-310) to replace the old, error-prone `java.util.Date` and `Calendar`. Within it, there are two distinct ideas of "an amount of time," and the API gives each its own type so you cannot accidentally mix them. ### Two scales of time Think of two completely different rulers: - A **machine/physical ruler** measures *exact elapsed time* — seconds, milliseconds, nanoseconds. One second is always the same length everywhere. This is what `Duration` represents. - A **calendar/human ruler** measures *date offsets* — years, months, days. These units do **not** have a fixed length: a month can be 28, 29, 30, or 31 days; a year can be 365 or 366 days. This is what `Period` represents. ### `Duration` — time-based, exact - Internally stores a `long` count of **seconds** plus an `int` count of **nanoseconds** (0–999,999,999). That's it — no concept of days-as-calendar. - Created with factories like `Duration.ofHours(2)`, `Duration.ofMinutes(90)`, `Duration.ofSeconds(30)`, `Duration.ofMillis(...)`, `Duration.ofNanos(...)`, or `Duration.of(2, ChronoUnit.HOURS)`. - Note: `Duration.ofDays(1)` exists, but it means **exactly 24 hours** (86,400 seconds), not "the next calendar day." That distinction matters across Daylight Saving Time (see below). - Works with **time-containing** temporals: `Instant`, `LocalTime`, `LocalDateTime`, `ZonedDateTime`, `OffsetDateTime`. You can do `instant.plus(duration)`. - Read it with `getSeconds()`/`getNano()` or the Java 9+ `toHours()`, `toMinutes()`, `toDaysPart()`, `toHoursPart()`, etc. ### `Period` — date-based, calendar-aware - Internally stores three `int` fields: **years, months, days** — independently. It does *not* normalize days into months. - Created with `Period.ofYears(1)`, `Period.ofMonths(2)`, `Period.ofDays(10)`, or `Period.of(1, 2, 10)` (1 year, 2 months, 10 days). - Works with **date** temporals: `LocalDate`. `date.plus(period)` is calendar arithmetic, so adding one month to Jan 31 yields Feb 28/29 (clamped to the valid end-of-month), and adding a year across a leap boundary is handled correctly. - Read it with `getYears()`, `getMonths()`, `getDays()`. ### Why they are not interchangeable Because calendar units are variable-length, a `Period` of "1 month" has **no fixed number of seconds** — it depends on *which* month and *which* starting date. A `Duration` of "30 days" is always 2,592,000 seconds. Mixing them would lose this meaning, so the API keeps them separate and even throws if you use the wrong one against the wrong temporal (e.g. `LocalDate.plus(aDuration)` throws `UnsupportedTemporalTypeException` because a date has no time component to add seconds to). ### The decision rule - Exact elapsed time, timeouts, performance measurements, machine-to-machine intervals → **Duration**. - Human calendar offsets — "a month's notice," "valid for 1 year," "3 days from the order date" → **Period**. Both are **immutable** and **thread-safe**, like the rest of `java.time`. Both implement `TemporalAmount`, which is the interface `plus`/`minus` accept.
- Why can a Period not be converted to a fixed number of seconds without more information?Because months and years are variable-length calendar units; you need the actual start date to know how many days (and thus seconds) elapse. Only with an anchor date can you resolve a Period to a concrete day/second count.
- Which type implements TemporalAmount, and why does that matter?Both Duration and Period implement TemporalAmount, which is what Temporal.plus/minus accept — so both can be passed to plus/minus, but each is only valid against temporals that support its units.
saying these in an interview costs you the question
- Saying Period stores time (it has no hours/minutes/seconds)
- Claiming Duration.ofDays(1) means the next calendar day — it's exactly 24h
- Thinking they're interchangeable / can both be added to any temporal
- Believing a Period of 1 month always equals 30 days of seconds