DateTimeFormatter in Java
The DateTimeFormatter class in Java, in java.time.format, is used to format a date or time as text, such as turning 2026-11-12 into "12 Nov 2026", and to parse text back into a date or time. It replaces the old SimpleDateFormat, and unlike that class it is immutable and thread-safe, so one formatter can be shared everywhere. In this lesson, you will learn the built-in formatters, how to write your own patterns, and how to handle parsing errors.
Creating a Formatter
| Way | Example |
|---|---|
| A built-in ISO formatter | DateTimeFormatter.ISO_LOCAL_DATE |
| A pattern | DateTimeFormatter.ofPattern("dd-MM-yyyy") |
| A pattern in a language | DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.FRENCH) |
| A localized style | DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG) |
Pattern Letters
| Letter | Meaning | Example |
|---|---|---|
yyyy | Year | 2026 |
MM / MMM / MMMM | Month as number, short name, full name | 11 / Nov / November |
dd / d | Day of month, with or without a leading zero | 05 / 5 |
EEE / EEEE | Day of week, short or full | Thu / Thursday |
HH | Hour, 0 to 23 | 14 |
hh | Hour, 1 to 12 | 02 |
mm | Minute (lowercase!) | 47 |
ss | Second | 31 |
a | AM or PM | PM |
VV / z | Zone ID or zone name | Asia/Kolkata / IST |
'text' | Literal text in quotes | 'at' |
Example: Formatting
Let's see an example that formats one date and time in several ways.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Formatting {
public static void main(String[] args) {
LocalDateTime t = LocalDateTime.of(2026, 11, 12, 14, 47, 31);
System.out.println(t.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println(t.format(DateTimeFormatter.ofPattern("dd-MM-yyyy")));
System.out.println(t.format(
DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy", Locale.ENGLISH)));
System.out.println(t.format(
DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH)));
System.out.println(t.format(DateTimeFormatter.ofPattern(
"'Exam on' dd MMM 'at' HH:mm", Locale.ENGLISH)));
System.out.println(t.format(
DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.FRENCH)));
}
}2026-11-12T14:47:31
12-11-2026
Thursday, 12 November 2026
02:47 PM
Exam on 12 Nov at 14:47
12 novembre 2026Explanation: The ISO formatter gives the standard machine format. Each pattern lays out the parts you choose. Words in single quotes are copied as they are. The locale decides the language of month and day names, so the same pattern gives "November" in English and "novembre" in French.
Example: Parsing
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
public class Parsing {
public static void main(String[] args) {
DateTimeFormatter indian = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate birthday = LocalDate.parse("15/03/2012", indian);
System.out.println("Parsed: " + birthday + ", a "
+ birthday.getDayOfWeek());
LocalTime alarm = LocalTime.parse("06:30");
System.out.println("Alarm: " + alarm);
System.out.println("Smart: " + LocalDate.parse("31/02/2026", indian));
DateTimeFormatter strict = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
try {
LocalDate.parse("31/02/2026", strict);
} catch (DateTimeParseException e) {
System.out.println("Strict: " + e.getMessage());
}
}
}Parsed: 2012-03-15, a THURSDAY
Alarm: 06:30
Smart: 2026-02-28
Strict: Text '31/02/2026' could not be parsed: Invalid date 'FEBRUARY 31'Explanation: LocalDate.parse(text, formatter) reads text using the pattern. Without a formatter, parse expects ISO text such as "06:30". Note the surprise: by default, a formatter uses the smart resolver, which quietly turns 31 February into 28 February. A formatter with ResolverStyle.STRICT rejects it with DateTimeParseException. Strict mode needs uuuu (the proleptic year) instead of yyyy. Text that can never be valid, such as day 32, throws even in smart mode.
Common Mistakes
Writing "dd-mm-yyyy". mm is minutes; use MM for months.
Writing "YYYY". Y is the week-based year, which differs from the calendar year around New Year; use yyyy.
Validating user input with the default (smart) resolver. It turns 31 February into 28 February; use ResolverStyle.STRICT with uuuu.
Formatting month names without a locale. The result depends on the computer's language; pass Locale.ENGLISH or the user's locale.
Interview Corner
Why is DateTimeFormatter preferred over SimpleDateFormat?
DateTimeFormatter is immutable and thread-safe, so a single instance can be shared, whereas SimpleDateFormat keeps internal state and gives wrong results when shared between threads. DateTimeFormatter works with the java.time types, has strict and clear parsing errors through DateTimeParseException, and offers built-in ISO and localized formats.
Practice
- Easy: Format today's date as "Thursday 12/11/2026" and as "12th of November" (hint: build the "th" yourself).
- Harder: Read dates typed in the format
dd-MM-yyyy, ask again when the input is invalid, and print how many days remain until each date.
Key Takeaways
Was this tutorial helpful?