On this page
Date/Time Formatting
DateTimeFormatter provides thread-safe formatting and parsing for all java.time types.
Basic Formatting
LocalDate date = LocalDate.of(2024, 6, 15);
LocalDateTime dateTime = LocalDateTime.of(2024, 6, 15, 14, 30, 45);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(date.format(formatter)); // 2024-06-15
DateTimeFormatter dateTimeFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTime.format(dateTimeFmt)); // 2024-06-15 14:30:45
Predefined Formatters
LocalDate date = LocalDate.now();
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2024-06-15
System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE)); // 20240615
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2024-06-15T14:30:45
Instant instant = Instant.now();
System.out.println(DateTimeFormatter.ISO_INSTANT.format(instant)); // 2024-06-15T06:30:45Z
Common Pattern Letters
| Pattern | Meaning | Example |
|---|---|---|
yyyy |
4-digit year | 2024 |
MM |
2-digit month | 06 |
MMM |
Abbreviated month | Jun |
MMMM |
Full month | June |
dd |
2-digit day | 15 |
EEE |
Abbreviated day | Sat |
HH |
Hour (0-23) | 14 |
mm |
Minute | 30 |
ss |
Second | 45 |
SSS |
Millisecond | 123 |
a |
AM/PM marker | PM |
z |
Timezone name | CST |
Z |
Timezone offset | +0800 |
X |
ISO 8601 offset | +08:00 |
Parsing
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date = LocalDate.parse("15/06/2024", fmt);
LocalDateTime dt = LocalDateTime.parse("15/06/2024 14:30",
DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
Strict vs Lenient
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd")
.withResolverStyle(ResolverStyle.STRICT);
// Throws exception for invalid dates like 2024-02-30
LocalDate.parse("2024-02-30", fmt);
Locale-Sensitive Formatting
LocalDate date = LocalDate.of(2024, 6, 15);
DateTimeFormatter usFmt = DateTimeFormatter
.ofPattern("MMMM dd, yyyy", Locale.US);
System.out.println(date.format(usFmt)); // June 15, 2024
DateTimeFormatter cnFmt = DateTimeFormatter
.ofPattern("yyyy年MM月dd日", Locale.CHINA);
System.out.println(date.format(cnFmt)); // 2024年06月15日
Formatting ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(
"yyyy-MM-dd HH:mm:ss z", Locale.ENGLISH);
System.out.println(zdt.format(fmt)); // 2024-06-15 14:30:00 CST
Reusable Formatter
DateTimeFormatter is immutable and thread-safe — create once, reuse everywhere:
public class DateFormats {
public static final DateTimeFormatter DATE =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static final DateTimeFormatter DATETIME =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static final DateTimeFormatter ISO =
DateTimeFormatter.ISO_OFFSET_DATE_TIME;
}
Unlike SimpleDateFormat, no synchronization needed.
Best Practices
- Store
DateTimeFormatteras static constants — they are thread-safe - Use ISO format (
ISO_LOCAL_DATE,ISO_INSTANT) for APIs and storage - Always specify a
Localefor user-facing formatted output - Use
ResolverStyle.STRICTwhen parsing user input - Prefer
DateTimeFormatteroverSimpleDateFormatin all new code