DATE, TIME, AND LOCALIZATION
Date and Time Formatting
Rule: DateTimeFormatter provides flexible formatting and parsing for date/time objects.
- Predefined formatters: ISO_LOCAL_DATE, ISO_LOCAL_TIME, etc.
- Pattern-based formatters: Custom patterns using letters (yyyy, MM, dd)
- Localized formatters: Locale-specific formatting
import java.time.*;
import java.time.format.*;
import java.util.Locale;
LocalDateTime dateTime = LocalDateTime.of(2024, 3, 15, 14, 30, 45);
// Predefined formatters
System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2024-03-15
System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME)); // 14:30:45
System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2024-03-15T14:30:45
// Custom patterns
DateTimeFormatter custom1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter custom2 = DateTimeFormatter.ofPattern("MMM dd, yyyy 'at' h:mm a");
DateTimeFormatter custom3 = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy");
System.out.println(dateTime.format(custom1)); // 2024-03-15 14:30:45
System.out.println(dateTime.format(custom2)); // Mar 15, 2024 at 2:30 PM
System.out.println(dateTime.format(custom3)); // Friday, March 15, 2024
// Localized formatting
DateTimeFormatter usFormat = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.US);
DateTimeFormatter frenchFormat = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.FRANCE);
System.out.println(dateTime.format(usFormat)); // Mar 15, 2024, 2:30:45 PM
System.out.println(dateTime.format(frenchFormat)); // 15 mars 2024, 14:30:45
Parsing strings to date/time:
// Parse with predefined formatters
LocalDate date1 = LocalDate.parse("2024-03-15", DateTimeFormatter.ISO_LOCAL_DATE);
LocalTime time1 = LocalTime.parse("14:30:45", DateTimeFormatter.ISO_LOCAL_TIME);
// Parse with custom patterns
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/dd/yyyy h:mm a");
LocalDateTime parsed = LocalDateTime.parse("03/15/2024 2:30 PM", parser);
// Case-insensitive parsing
DateTimeFormatter flexible = DateTimeFormatter.ofPattern("MMM dd, yyyy")
.withResolverStyle(ResolverStyle.LENIENT)
.withLocale(Locale.ENGLISH);
LocalDate flexible_date = LocalDate.parse("mar 15, 2024", flexible);
// Handling parse errors
try {
LocalDate invalid = LocalDate.parse("invalid-date");
} catch (DateTimeParseException e) {
System.out.println("Parse error: " + e.getMessage());
System.out.println("Error index: " + e.getErrorIndex());
}
Pattern symbols:
// Common pattern symbols
// y - year (yyyy = 2024, yy = 24)
// M - month (MM = 03, MMM = Mar, MMMM = March)
// d - day of month (dd = 15)
// H - hour 24-hour (HH = 14)
// h - hour 12-hour (hh = 02)
// m - minute (mm = 30)
// s - second (ss = 45)
// a - AM/PM marker
// E - day of week (EEE = Fri, EEEE = Friday)
// z - time zone name (PST, Pacific Standard Time)
// Z - time zone offset (-0800)
DateTimeFormatter complex = DateTimeFormatter.ofPattern(
"EEEE, MMMM d, yyyy 'at' h:mm:ss a z"
);
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println(zdt.format(complex));
// Friday, March 15, 2024 at 2:30:45 PM PDT
Thread safety and performance:
// DateTimeFormatter is immutable and thread-safe
public class DateFormatter {
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public String format(LocalDateTime dateTime) {
return dateTime.format(FORMATTER); // Safe to share
}
}
// Reuse formatters for better performance
DateTimeFormatter reusable = DateTimeFormatter.ofPattern("yyyy-MM-dd");
List<LocalDate> dates = Arrays.asList(/* many dates */);
// ✅ Efficient - reuse formatter
dates.stream()
.map(date -> date.format(reusable))
.forEach(System.out::println);
// ❌ Inefficient - create new formatter each time
dates.stream()
.map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.forEach(System.out::println);
💡 Learning Tip: Remember “PATTERN = PICTURE” - yyyy-MM-dd shows exactly how the output looks. DateTimeFormatter is thread-safe and should be reused.