DateTimeFormatter

Basic Java
≈ 2 min read

A date inside a program and a date for a person are different representations

A LocalDate object stores a date, while a string such as 18.09.2026 is only its textual representation. Instead of assembling strings manually or parsing them with split(), Java uses DateTimeFormatter.

Formatting

A formatter can be created from a pattern and then passed to the format() method.

LocalDate date = LocalDate.of(2026, 9, 18);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");

String text = date.format(formatter);
System.out.println(text); // 18.09.2026

Letters in the pattern have special meanings: for example, dd is the day of month, MM is the month number, and yyyy is the year. Case matters: MM and mm represent different fields.

Parsing

The same formatter can be used in the opposite direction:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
LocalDate date = LocalDate.parse("18.09.2026", formatter);

If the text does not match the expected format or contains an impossible date, parsing ends with a DateTimeParseException. That is better than silently producing an incorrect value.

Ready-made ISO formats

For standard machine-readable formats, a custom pattern is often unnecessary. DateTimeFormatter provides ready-made formatters such as ISO_LOCAL_DATE, ISO_LOCAL_DATE_TIME, and ISO_INSTANT. The parse() methods of many classes already use a suitable ISO format by default.

LocalDate date = LocalDate.parse("2026-09-18");
Instant instant = Instant.parse("2026-09-18T09:30:00Z");

Locale for human-readable text

If a pattern contains month or weekday names, the result depends on the language. The language should be specified explicitly with Locale when the format is part of a user interface or an external contract.

DateTimeFormatter formatter = DateTimeFormatter
        .ofPattern("d MMMM yyyy", Locale.forLanguageTag("ru"));

String text = LocalDate.of(2026, 9, 18).format(formatter);
Do not mix storage with presentation. It is better to keep a date or time object in the application model and convert it to text at the boundary: during input, output, serialization, or data exchange.