Date-Time Arithmetic in Java
Java’s date/time API provides immutable operations for adding and subtracting temporal amounts, with behavior determined by the specific temporal type. Choosing the right amount type and understanding calendar-based versus duration-based arithmetic are central to correct backend code.
Java’s modern date/time API represents arithmetic through methods such as `plus(...)`, `minus(...)`, and type-specific operations like `plusDays(...)`. These methods do not mutate the original temporal object; they return a new value containing the requested adjustment.
Calendar-based arithmetic is especially important for types such as `LocalDate` and `ZonedDateTime`. Adding one day means advancing the calendar date, while adding a fixed `Duration` means adding an exact number of seconds and nanoseconds. Around daylight-saving transitions, those operations can produce different local clock times.
`Period` is designed for date-based amounts such as years, months, and days, whereas `Duration` represents time-based amounts such as seconds and nanoseconds. A `Period` is generally appropriate for calendar concepts like “one month later,” while a `Duration` is appropriate for elapsed-time concepts like “two hours later.”
The temporal type also determines which operations are valid. For example, `LocalDate` supports date-based arithmetic but has no time-of-day component, while `LocalDateTime` has both date and time but no time-zone or offset information. `Instant` represents a point on the UTC timeline and is naturally suited to elapsed-time calculations.
Month arithmetic has special rules because months have different lengths. For example, adding one month to January 31 cannot preserve day 31 in February, so Java adjusts the resulting date to the last valid day of the target month. Interview answers should mention immutability, the distinction between `Period` and `Duration`, and the temporal type’s rules.
Key points
- Date/time arithmetic is immutable: operations return a new temporal value.
- Use `Period` for calendar-based date amounts and `Duration` for elapsed-time amounts.
- `ZonedDateTime` arithmetic can behave differently across daylight-saving transitions.
- Month-based arithmetic must account for months with different numbers of days.
- The supported arithmetic depends on the temporal type being used.
Interview questions
What happens when you add one month to January 31?
Java cannot create a date such as February 31 because it is invalid. Month-based arithmetic adjusts the result to the last valid day of the target month. For example, January 31 plus one month becomes February 28 in a non-leap year and February 29 in a leap year.
Are Java date/time objects mutable when you call `plusDays()`?
No. The modern Java date/time types are immutable. An operation such as `plusDays()` returns a new temporal value and leaves the original unchanged. If the result is needed later, it must be assigned to a variable or otherwise used.
What is the difference between `Period` and `Duration`?
`Period` represents date-based amounts such as years, months, and days. `Duration` represents time-based amounts using seconds and nanoseconds. The distinction matters because calendar arithmetic and elapsed-time arithmetic do not always have equivalent results, especially around daylight-saving changes or variable-length months.
Why can `Period.ofDays(1)` and `Duration.ofDays(1)` produce different results with a `ZonedDateTime`?
A date-based amount advances the calendar according to the temporal type’s calendar rules. A duration represents a fixed amount of elapsed time, namely 24 hours for one day. Across a daylight-saving transition, a local calendar day can contain fewer or more than 24 elapsed hours, so the resulting local time can differ.
How would you choose a Java temporal type for a scheduled backend event?
The choice depends on what the event means. If it is an absolute moment, such as an event timestamp stored for auditing, `Instant` is usually appropriate. If the event is defined by a local wall-clock time in a particular region, `ZonedDateTime` may be required. A `LocalDateTime` is suitable only when zone and offset information are intentionally outside the value’s meaning.