Java DateTimeFormatter class, added in Java 8 Date Time API changes, helps in uniformly parsing and printing the date-time objects in various inbuilt and custom formatting patterns. Its instances are thread-safe and immutable; and can be used without introducing concurrency issues.
In this tutorial, we will learn to create DateTimeFormatter
instance and using predefined and custom patterns for formatting ZonedDateTime
, LocalDateTime
, LocalDate
and LocalTime
instances.
public static final DateTimeFormatter ZDT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a z");
//Formatting
String str = ZDT_FORMATTER.format( ZonedDateTime.now() ); //2023-04-26 15:28:29 pm IST
//Parsing
ZonedDateTime zdt = ZonedDateTime.parse( str, ZDT_FORMATTER );
1. Formatting Patterns with DateTimeFormatter
An instance of DateTimeFormatter is always associated with a formatting pattern, it is created with. We can either use an inbuilt pattern or we can supply a custom pattern.
1.1. Using Pre-built Instances
There are two ways to refer to the inbuilt patterns:
- Using prebuilt instances of DateTimeFormatter, such as
ISO_DATE
,ISO_LOCAL_DATE
,BASIC_ISO_DATE
,ISO_LOCAL_DATE_TIME
,RFC_1123_DATE_TIME
etc. Most instances are ISO-8601 compliant.
DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2023, 4, 25));
- Using one of the following prebuilt localized styles with
FormatStyle
.
FormatStyle | Pattern Example |
---|---|
FULL | Tuesday, April 25, 2023 |
LONG | April 25, 2023 |
MEDIUM | Apr 25, 2023 |
SHORT | 4/25/23 |
DateTimeFormatter customFormatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG );
1.2. Custom Patterns
We can supply a custom pattern built with pattern characters such as ‘uuuu-MMM-dd‘ and use ofPattern() method to create a new instance.
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mma z");
1.3. DateTimeFormatterBuilder for Complex Patterns
Use DateTimeFormatterBuilder
to create a more complex formatter instance.
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern(".SSS")
.optionalEnd()
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.optionalStart()
.appendOffset("+HHMM", "0000")
.optionalEnd()
.toFormatter();
2. Date Time Formatting
2.1. Syntax
The DateTimeFormatter class provides mainly one method to format a given date-time instance of TemporalAccessor type which is the base interface type for date, time and offset objects. It formats the dateTimeObject instance using the specified format.
String format(TemporalAccessor temporal) # Formats a date-time object using this formatter.
2.2. Format ZonedDateTime, LocalDateTime, LocalDate, LocalTime
We saw an example of formatting ZonedDateTime in the previous section. Let us learn to format other classes.
LocalDateTime does not have a timezone part so create the pattern accordingly.
DateTimeFormatter FOMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm a");
String output = FOMATTER.format( LocalDateTime.now() ); // 07/15/2018 at 02:49 PM
LocalDate does not have time and timezone parts. So create the pattern accordingly.
DateTimeFormatter FOMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy");
String dateString = FOMATTER.format( LocalDate.now() ); // 07/15/2018
LocalTime does not have the date and timezone parts so create the pattern accordingly.
DateTimeFormatter FOMATTER = DateTimeFormatter.ofPattern("hh:mm a");
String localTimeString = FOMATTER.format( LocalTime.now() ); // 02:53 PM
3. Parsing
We can use any of the above-created DateTimeFormatter instances in parse() method to get the instance of that date/time object.
ZonedDateTime zdt = ZonedDateTime.parse( str, ZDT_FORMATTER );
4. Useful Custom Patterns
The custom patterns are built using special letters that have special meanings during the formatting or parsing. Here are some common pattern symbols:
- ‘y’: year
- ‘M’: month (in number form, e.g. “1” for January)
- ‘MMM’: month abbreviation (e.g. “Jan”)
- ‘MMMM’: full month name (e.g. “January”)
- ‘d’: day of the month
- ‘E’: day of week abbreviation (e.g. “Mon”)
- ‘EEEE’: full day of week name (e.g. “Monday”)
- ‘h’: hour (in 1-12 form)
- ‘H’: hour (in 0-23 form)
- ‘m’: minute
- ‘s’: second
- ‘S’: fraction of second
- ‘a’: AM/PM marker
- ‘z’: time zone abbreviation (e.g. “PST”)
- ‘Z’: time zone offset (e.g. “-0800”)
Using the above letters, we have built the following ready-to-use custom patterns.
Pattern | Example |
---|---|
yyyy-MM-dd (ISO) | “2018-07-14” |
dd-MMM-yyyy | “14-Jul-2018” |
dd/MM/yyyy | “14/07/2018” |
E, MMM dd yyyy | “Sat, Jul 14 2018” |
h:mm a | “12:08 PM” |
EEEE, MMM dd, yyyy HH:mm:ss a | “Saturday, Jul 14, 2018 14:31:06 PM” |
yyyy-MM-dd'T'HH:mm:ssZ | “2018-07-14T14:31:30+0530” |
hh 'o''clock' a, zzzz | “12 o’clock PM, Pacific Daylight Time” |
K:mm a, z | “0:08 PM, PDT” |
Happy Learning !!