1. DateTimeFormatter: what it is and why you need it
In real-world applications, dates rarely live only inside the code. Usually, you need to:
- Convert to a string for output to the console, the screen, or a file (for example, "01.06.2025 14:30").
- Parse a string, i.e., turn a string entered by a user or coming from a file back into a date/time object.
For this, Java provides a powerful and convenient tool — the class java.time.format.DateTimeFormatter.
You can think of DateTimeFormatter as a translator between time objects (LocalDate, LocalDateTime, ZonedDateTime, Instant, etc.) and strings. It can:
- Turn date/time objects into strings in the required format (format — formatting).
- Turn strings into date/time objects (parse — parsing).
2. Built-in formatters: quick and easy
Java thoughtfully provides a set of built-in formatters that cover the most popular ISO formats (international standards for dates and times).
Here are some of them:
| Formatter | Example string | Description |
|---|---|---|
|
2025-06-01 | Date only (year-month-day) |
|
14:30:00 | Time only (hours:minutes:seconds) |
|
2025-06-01T14:30:00 | Date and time without time zone |
|
2025-06-01T14:30:00+03:00[Europe/Minsk] | Date, time, and time zone |
Example: using a standard formatter
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class FormatterDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.now();
// Format the date to a string
String text = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(text); // For example, 2025-06-01
// Parse the string back to a date
LocalDate parsed = LocalDate.parse("2025-06-01", DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(parsed); // 2025-06-01
}
}
Analogy
If Java were a coffee shop, the standard formatters would be “americano,” “latte,” and “espresso.” Quick and standard — but sometimes you want something special!
3. Custom patterns: DateTimeFormatter.ofPattern
Sometimes the built-in formats aren’t enough. For example, you need to print the date as "01.06.2025 14:30" rather than "2025-06-01T14:30:00". To do that, you can create your own pattern using the method DateTimeFormatter.ofPattern(String pattern).
Pattern syntax
Patterns use special letters:
- y — year (yyyy — 2025)
- M — month (MM — 06)
- d — day (dd — 01)
- H — hour (24-hour format, HH — 14)
- m — minutes (mm — 30)
- s — seconds (ss — 00)
Pattern examples
| Pattern | Example result |
|---|---|
|
01.06.2025 |
|
2025/06/01 |
|
01.06.2025 14:30 |
|
2025-06-01 14:30:00 |
|
1 June 2025 (with Russian locale) |
Example: formatting date and time
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CustomFormatDemo {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2025, 6, 1, 14, 30);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
String text = dt.format(formatter);
System.out.println(text); // 01.06.2025 14:30
}
}
Example: parsing a string into a date
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ParseDemo {
public static void main(String[] args) {
String input = "01.06.2025 14:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
LocalDateTime dt = LocalDateTime.parse(input, formatter);
System.out.println(dt); // 2025-06-01T14:30
}
}
Attention: the pattern must exactly match the string! If the string contains seconds, add :ss to the pattern.
4. Formatting: turning date/time into a string
General workflow
- Create the needed object (LocalDate, LocalDateTime, ZonedDateTime, etc.).
- Create or choose the appropriate formatter.
- Call the object's format(DateTimeFormatter) method to get a string.
Example: print a date in different formats
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class MultiFormatDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
// Standard ISO
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2025-06-01
// Custom format
DateTimeFormatter rusFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
System.out.println(date.format(rusFormat)); // 01.06.2025
// English style
DateTimeFormatter usFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(date.format(usFormat)); // 06/01/2025
}
}
Formatting time
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class TimeFormatDemo {
public static void main(String[] args) {
LocalTime time = LocalTime.of(14, 30, 5);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(time.format(formatter)); // 14:30:05
}
}
5. Parsing: turning a string into date/time
General workflow
- Get the string (for example, from the user).
- Create a formatter with the same pattern as the string.
- Call the static parse() method or the formatter's parse() method.
Example: parsing a date
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class ParseDateDemo {
public static void main(String[] args) {
String input = "01.06.2025";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
LocalDate date = LocalDate.parse(input, formatter);
System.out.println(date); // 2025-06-01
}
}
Example: parsing date and time
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ParseDateTimeDemo {
public static void main(String[] args) {
String input = "01.06.2025 14:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(input, formatter);
System.out.println(dateTime); // 2025-06-01T14:30
}
}
6. Handling parsing errors
Parsing can be tricky. If the string does not match the pattern, Java will throw a DateTimeParseException. This is normal — for example, when a user enters a date with a mistake.
Example: handling parsing errors
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class ParseErrorDemo {
public static void main(String[] args) {
String input = "32.13.2025"; // Invalid date
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
try {
LocalDate date = LocalDate.parse(input, formatter);
System.out.println(date);
} catch (DateTimeParseException ex) {
System.out.println("Parsing error: " + ex.getMessage());
}
}
}
Important: always handle such errors when working with user input!
7. Practice: transforming dates for the user
Suppose in our training app there’s a task: the user enters a birth date in the format "dd.MM.yyyy", and the program must output the date in the format "yyyy/MM/dd", as well as the day of the week.
Example
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Scanner;
public class BirthdayFormatDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter birth date (dd.MM.yyyy): ");
String input = scanner.nextLine();
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd");
try {
LocalDate birthday = LocalDate.parse(input, inputFormat);
String formatted = birthday.format(outputFormat);
System.out.println("Your date in the new format: " + formatted);
System.out.println("Day of week: " + birthday.getDayOfWeek()); // For example, SATURDAY
} catch (DateTimeParseException ex) {
System.out.println("Error: invalid date format!");
}
}
}
8. Localization: how language affects formatting
With DateTimeFormatter, you can not only change the order of numbers but also output the month in words, the day of the week, etc. The locale (language and region) is taken into account.
Example: month name in Russian
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LocaleDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", new Locale("ru"));
System.out.println(date.format(formatter)); // 1 June 2025
}
}
Example: English locale
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LocaleEnDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.ENGLISH);
System.out.println(date.format(formatter)); // 1 June 2025
}
}
Pro tip: if you want the month and day of week to be in the desired language, specify the locale explicitly!
9. Common mistakes when formatting and parsing dates
Error #1: Pattern and string mismatch.
If the string is "01.06.2025 14:30" but the pattern is "dd.MM.yyyy", parsing will fail. The pattern must exactly match the string.
Error #2: Pattern letters mixed up.
MM is month, mm is minutes. If you write "dd.mm.yyyy", Java will assume you mean minutes and throw an error. Always use uppercase M for month.
Error #3: Unhandled exceptions during parsing.
If you don’t catch DateTimeParseException, the program may terminate unexpectedly on invalid user input. Always handle such errors.
Error #4: Locale not specified when using words.
If you use a pattern with the month in words (MMMM) and don’t specify a locale, Java may use the default language (for example, English). Always set the desired locale explicitly.
Error #5: Using old classes (SimpleDateFormat, Date) in new projects.
Remember: in modern code, use only java.time and DateTimeFormatter.
GO TO FULL VERSION