Of course! Converting a java.time object to a String is a very common task in Java. The modern and recommended way to do this is using the DateTimeFormatter class.

Here’s a complete guide covering the most common scenarios.
The Key Class: DateTimeFormatter
The java.time.format.DateTimeFormatter class is the central tool for formatting (and parsing) date-time objects. It's flexible, thread-safe, and follows the ISO 8601 standard by default.
Basic Formatting (Using a Predefined Formatter)
For many common formats, you don't need to create a custom formatter. The DateTimeFormatter class provides several static constants.
Example: Formatting LocalDateTime
This is one of the most frequent use cases.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class BasicFormattingExample {
public static void main(String[] args) {
// Get the current date and time
LocalDateTime now = LocalDateTime.now();
// --- Using Predefined Formatters ---
// 1. ISO_LOCAL_DATE_TIME (e.g., 2025-10-27T10:15:30)
DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String isoString = now.format(isoFormatter);
System.out.println("ISO Format: " + isoString);
// 2. ISO_DATE_TIME (e.g., 2025-10-27T10:15:30.123456789)
DateTimeFormatter isoDateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;
String isoDateTimeString = now.format(isoDateTimeFormatter);
System.out.println("ISO DateTime Format: " + isoDateTimeString);
// 3. BASIC_ISO_DATE (e.g., 20251027)
DateTimeFormatter basicIsoFormatter = DateTimeFormatter.BASIC_ISO_DATE;
String basicIsoString = now.format(basicIsoFormatter);
System.out.println("Basic ISO Date Format: " + basicIsoString);
}
}
Output:
ISO Format: 2025-10-27T10:15:30.123456789
ISO DateTime Format: 2025-10-27T10:15:30.123456789
Basic ISO Date Format: 20251027
Custom Formatting (Using a Pattern)
For specific application requirements (like "MM/dd/yyyy" or "dd-MMM-yyyy"), you define a pattern string.
Common Pattern Symbols:
| Symbol | Meaning | Example |
|---|---|---|
y |
Year | 2025, 23 |
M |
Month in year | 10, Oct |
d |
Day in month | 27 |
H |
Hour in day (0-23) | 13 |
h |
Hour in am/pm (1-12) | 1 |
m |
Minute in hour | 45 |
s |
Second in minute | 30 |
S |
Fraction of second | 123 |
a |
Am-pm marker | PM |
z |
Time zone name | PST, America/Los_Angeles |
Z |
Time zone offset | -0800, -08:00 |
Example: Custom Pattern for LocalDate
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class CustomFormattingExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
// Define a custom pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy");
// Format the date
String formattedDate = today.format(formatter);
System.out.println("Today is: " + formattedDate); // e.g., October 27, 2025
}
}
More Custom Pattern Examples:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class MoreCustomFormatting {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
// Example 1: Short date format (e.g., 10/27/23)
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("MM/dd/yy");
System.out.println("Short Date: " + now.format(f1));
// Example 2: Time with AM/PM (e.g., 02:30:15 PM)
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("hh:mm:ss a");
System.out.println("12-Hour Time: " + now.format(f2));
// Example 3: Full date and time with timezone (e.g., Fri, Oct 27 2025 02:30:15 GMT)
DateTimeFormatter f3 = DateTimeFormatter.ofPattern("EEE, MMM d yyyy HH:mm:ss z");
System.out.println("Full Date/Time: " + now.format(f3));
}
}
Output:
Short Date: 10/27/23
12-Hour Time: 02:30:15 PM
Full Date/Time: Fri, Oct 27 2025 14:30:15 GMT
Formatting Different java.time Types
The format() method is available on all major date-time classes.

LocalDate
LocalDate date = LocalDate.of(2025, 12, 25);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy");
String result = date.format(formatter); // "Monday, December 25, 2025"
System.out.println(result);
LocalTime
LocalTime time = LocalTime.of(14, 30, 0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a");
String result = time.format(formatter); // "2:30 PM"
System.out.println(result);
ZonedDateTime (with Time Zone)
This is crucial for applications dealing with different time zones.
import java.time.ZonedDateTime;
import java.time.ZoneId;
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm z");
String result = zonedDateTime.format(formatter); // e.g., "2025-10-27 10:30 EDT"
System.out.println(result);
Formatting vs. Parsing
Remember, DateTimeFormatter is a two-way street. You can also convert a String back into a date-time object using the parse() method.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class ParsingExample {
public static void main(String[] args) {
String dateString = "October 27, 2025";
// 1. Create the same formatter you used for formatting
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy");
// 2. Parse the string into a LocalDate object
LocalDate date = LocalDate.parse(dateString, formatter);
System.out.println("Parsed date: " + date); // 2025-10-27
System.out.println("Day of week: " + date.getDayOfWeek()); // FRIDAY
}
}
Important: Legacy java.util.Date and SimpleDateFormat
Before Java 8, developers used java.util.Date and the notoriously problematic SimpleDateFormat.
Why you should avoid SimpleDateFormat:
- Not Thread-Safe:
SimpleDateFormatis mutable and not thread-safe. Using it in a multi-threaded application (like a web server) can lead toIllegalArgumentExceptionand incorrect dates. You have to create a new instance for every use, which is inefficient. - Less Flexible: API is clunkier compared to
DateTimeFormatter.
Comparison:
| Feature | java.time.format.DateTimeFormatter (Modern) |
java.text.SimpleDateFormat (Legacy) |
|---|---|---|
| Thread Safety | Immutable and Thread-Safe | Mutable and Not Thread-Safe |
| API | Fluent, clear, and powerful | Clunky and error-prone |
| Default Pattern | Follows ISO 8601 standards | Locale-dependent |
| Recommendation | Always use this | Avoid |
Summary
| Goal | Code Snippet |
|---|---|
| Get a default ISO format string | LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); |
| Format with a custom pattern | LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); |
Format a ZonedDateTime with a time zone |
ZonedDateTime.now(ZoneId.of("UTC")).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); |
| Parse a string back to a date | LocalDate.parse("2025-12-25", DateTimeFormatter.ISO_LOCAL_DATE); |
| Thread-safe formatting | ` |
