skip to content

How are months and days-of-week numbered in java.time, and why does it matter?

level: juniorimportance: should knowfreq 55%

answer

  1. Month: 1 = January, 12 = December
  2. Old Calendar was 0-based — the trap
  3. DayOfWeek: MONDAY = 1, SUNDAY = 7 (ISO)
  4. Prefer Month / DayOfWeek enums over ints
  5. Month 0 throws DateTimeException

basics

~20 s

In java.time months are 1-based: January is 1 and December is 12. Days of week are also 1-based with MONDAY = 1 and SUNDAY = 7. This is different from the old Calendar class, where January was 0.

solid answer

~40 s

Unlike the legacy java.util.Calendar (where January was 0 and December was 11), the modern java.time API uses natural, human numbering. Months run 1 (JANUARY) through 12 (DECEMBER), exposed both as the int from LocalDate.getMonthValue() and as the Month enum from getMonth(). Days of week run 1 (MONDAY) through 7 (SUNDAY) per ISO-8601, available as the DayOfWeek enum from getDayOfWeek() and its getValue(). This matters because code ported from Calendar, or written by habit, often introduces off-by-one bugs — e.g. LocalDate.of(2026, 0, 1) throws because month 0 is invalid, and LocalDate.of(year, month, day) expects the real month number. Prefer the Month and DayOfWeek enums over raw ints to make the intent explicit and avoid the off-by-one trap entirely.

code

java · 8 lines
java
LocalDate d = LocalDate.of(2026, Month.FEBRUARY, 14);
int m = d.getMonthValue();          // 2
Month month = d.getMonth();          // FEBRUARY
DayOfWeek dow = d.getDayOfWeek();    // SATURDAY
int dowNum = dow.getValue();         // 6  (Mon=1 .. Sun=7)

// This throws DateTimeException - no month 0:
// LocalDate.of(2026, 0, 1);

go deeper

for a junior

States that months are 1-based (Jan=1) and Monday=1, and contrasts it with the old 0-based Calendar.

for a middle

Knows getMonth() returns the Month enum vs getMonthValue() the int, that day-of-week follows ISO Mon=1..Sun=7, and that month 0 throws.

for a senior

Recommends using Month/DayOfWeek enums to eliminate the off-by-one class of bugs and is aware of locale/ISO week-start differences when interoperating.

for a principal

Establishes conventions and lint/code-review checks to catch legacy Calendar-style numbering during migrations and at API boundaries (e.g. external systems with 0-based or Sunday-first weeks).

## Why numbering is a common interview gotcha Before Java 8, dates were handled with `java.util.Calendar`. In `Calendar`, months were **0-based**: `Calendar.JANUARY == 0`, `Calendar.DECEMBER == 11`. This caused a famous class of off-by-one bugs. The modern `java.time` API deliberately fixed this by using **human-natural, 1-based** numbering. ## Months - `LocalDate.getMonthValue()` returns an `int` from **1 (January)** to **12 (December)**. - `LocalDate.getMonth()` returns a `Month` enum constant (e.g. `Month.JANUARY`). `Month.JANUARY.getValue()` is `1`. - Factory methods take the real number: `LocalDate.of(2026, 2, 14)` is 14 February 2026. Passing `0` or `13` throws `DateTimeException`. - You can also pass the enum: `LocalDate.of(2026, Month.FEBRUARY, 14)`, which is self-documenting. ## Days of week - `LocalDate.getDayOfWeek()` returns a `DayOfWeek` enum. - The numbering follows **ISO-8601**: `MONDAY = 1` … `SUNDAY = 7` (`DayOfWeek.MONDAY.getValue() == 1`). Note this differs from some locales/JS where Sunday is 0 or the week starts on Sunday. ## Terms defined - **Enum**: a fixed set of named constants. `Month` and `DayOfWeek` are enums, so the compiler restricts you to valid values and you get readable names instead of magic numbers. - **ISO-8601**: the international standard for date/time representation that java.time follows by default; it defines Monday as the first day of the week. ## Why it matters in practice 1. **Porting bugs**: code copied from `Calendar` may add or subtract 1 to a month, which is wrong in java.time. 2. **Validation**: `LocalDate.of(2026, 0, 1)` throws — there is no month 0. 3. **Readability/safety**: using the `Month`/`DayOfWeek` enums removes the numbering question entirely and is the recommended style. ## Example ```java LocalDate d = LocalDate.of(2026, Month.FEBRUARY, 14); int m = d.getMonthValue(); // 2 Month month = d.getMonth(); // FEBRUARY DayOfWeek dow = d.getDayOfWeek(); // SATURDAY int dowNum = dow.getValue(); // 6 (Mon=1 .. Sun=7) ```

  • What does LocalDate.of(2026, 0, 1) do?
    It throws a DateTimeException, because java.time months are 1-based and 0 is not a valid month.
  • What integer does DayOfWeek.SUNDAY.getValue() return?
    7. java.time follows ISO-8601 where Monday is 1 and Sunday is 7.

java.time counts like a human reading a calendar (January is the 1st month); the old Calendar counted like a C array starting at 0.

saying these in an interview costs you the question

  • Saying January is 0 (that was the old Calendar, not java.time)
  • Assuming Sunday = 0 or the week starts on Sunday
  • Adding/subtracting 1 to a month value out of Calendar habit
  • Believing getMonthValue() returns an enum (it returns an int)

context