Java DateTimeFormatter Tutorial with Examples
DateTimeFormatter class is a formatter for printing and parsing date-time objects since the introduction of Java 8 date time API.
Create DateTimeFormatter
You can create DateTimeFormatter in two ways:
- Use inbuilt pattern constants
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
- Use ofPattern() method
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss");
Predefined Formatters
DateTimeFormatter comes with multiple predefined date/time formats that follow ISO and RFC standards:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
public class DateTimeFormatterPredefinedExample {
static void print(String format, String result) {
System.out.printf("%s: %s\n", format, result);
}
public static void main(String[] args) {
print("ofLocalizedDate(*)", DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(LocalDate.now()));
print("ofLocalizedTime(*)", DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM).format(LocalTime.now()));
print("ofLocalizedDateTime(*)", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(LocalDateTime.now()));
print("ofLocalizedDateTime(*, *)", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT).format(LocalDateTime.now()));
print("BASIC_ISO_DATE", DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.now()));
print("ISO_LOCAL_DATE", DateTimeFormatter.ISO_LOCAL_DATE .format(LocalDate.now()));
print("ISO_OFFSET_DATE", DateTimeFormatter.ISO_OFFSET_DATE.format(OffsetDateTime.now()));
print("ISO_DATE", DateTimeFormatter.ISO_DATE.format(OffsetDateTime.now()));
print("ISO_LOCAL_TIME", DateTimeFormatter.ISO_LOCAL_TIME.format(LocalTime.now()));
print("ISO_OFFSET_TIME", DateTimeFormatter.ISO_OFFSET_TIME.format(OffsetTime.now()));
print("ISO_TIME", DateTimeFormatter.ISO_TIME.format(OffsetTime.now()));
print("ISO_LOCAL_DATE_TIME", DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now()));
print("ISO_OFFSET_DATE_TIME", DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.now()));
print("ISO_ZONED_DATE_TIME", DateTimeFormatter.ISO_ZONED_DATE_TIME.format(ZonedDateTime.now()));
print("ISO_DATE_TIME", DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now()));
print("ISO_ORDINAL_DATE", DateTimeFormatter.ISO_ORDINAL_DATE.format(ZonedDateTime.now()));
print("ISO_WEEK_DATE", DateTimeFormatter.ISO_WEEK_DATE.format(ZonedDateTime.now()));
print("ISO_INSTANT", DateTimeFormatter.ISO_INSTANT.format(ZonedDateTime.now()));
print("RFC_1123_DATE_TIME", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
}
}
ofLocalizedDate(*): 3 September, 2019 ofLocalizedTime(*): 12:28:39 AM ofLocalizedDateTime(*): 3 Sep, 2019 12:28:39 AM ofLocalizedDateTime(*, *): Tuesday, 3 September, 2019 12:28 AM BASIC_ISO_DATE: 20190903 ISO_LOCAL_DATE: 2019-09-03 ISO_OFFSET_DATE: 2019-09-03+08:00 ISO_DATE: 2019-09-03+08:00 ISO_LOCAL_TIME: 00:28:39.275 ISO_OFFSET_TIME: 00:28:39.277+08:00 ISO_TIME: 00:28:39.278+08:00 ISO_LOCAL_DATE_TIME: 2019-09-03T00:28:39.278 ISO_OFFSET_DATE_TIME: 2019-09-03T00:28:39.278+08:00 ISO_ZONED_DATE_TIME: 2019-09-03T00:28:39.279+08:00[Asia/Singapore] ISO_DATE_TIME: 2019-09-03T00:28:39.279+08:00[Asia/Singapore] ISO_ORDINAL_DATE: 2019-246+08:00 ISO_WEEK_DATE: 2019-W36-2+08:00 ISO_INSTANT: 2019-09-02T16:28:39.280Z RFC_1123_DATE_TIME: Tue, 3 Sep 2019 00:28:39 +0800
Each of these predefined DateTimeFormatter instances are preconfigured to format and parse date/times to/from different formats.
Using FormatStyle
In our examples earlier, we use FormatStyle to define on which format used for our date/time (see functions ofLocalizedDate(), ofLocalizedTime(), and ofLocalizedDateTime()). FormatStyle is an enumeration of the style of a localized date, time or date-time formatter. There are four constants:
- FULL: Full text style, with the most detail.
- LONG: Long text style, with lots of detail.
- MEDIUM: Medium text style, with some detail.
- SHORT: Short text style, typically numeric.
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
public class DateTimeFormatterFormatStyleExample {
static void print(String format, String result) {
System.out.printf("%s: %s\n", format, result);
}
public static void main(String[] args) {
LocalDate localDate = LocalDate.now();
System.out.println("*** LocalDate ***");
print("FULL", DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(localDate));
print("LONG", DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(localDate));
print("MEDIUM", DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(localDate));
print("SHORT", DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(localDate));
LocalTime localTime = LocalTime.now();
System.out.println("\n*** LocalTime ***");
print("MEDIUM", DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM).format(localTime));
print("SHORT", DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(localTime));
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("\n*** LocalDateTime ***");
print("MEDIUM", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(localDateTime));
print("SHORT", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(localDateTime));
}
}
*** LocalDate *** FULL: Tuesday, 3 September, 2019 LONG: 3 September, 2019 MEDIUM: 3 Sep, 2019 SHORT: 3/9/19 *** LocalTime *** MEDIUM: 2:05:19 AM SHORT: 2:05 AM *** LocalDateTime *** MEDIUM: 3 Sep, 2019 2:05:19 AM SHORT: 3/9/19 2:05 AM
If the FormatStyle is not supported in LocalTime, following exception will be thrown:
java.time.DateTimeException: Unable to extract value: class java.time.format.DateTimePrintContext$1
And if the FormatStyle is not supported in LocalDateTime:
java.time.DateTimeException: Unable to extract value: class java.time.LocalDateTime
Format Date/Time to String
We use format(...) method to convert Date/Time (in this case TemporalAccessor) to String:
- String format(TemporalAccessor temporal): Formats a date-time object using this formatter.
LocalDateTime localDT = LocalDateTime.now();
System.out.println(DateTimeFormatter.ofPattern("dd/MM/yyyy kk:mm:ss").format(localDT));
And the result is (may vary):
04/09/2019 23:22:33
Parse String to Date/Time
You can parse a String into a Date/Time instance using the parse() method
- TemporalAccessor parse(CharSequence text): Fully parses the text producing a temporal object.
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss.SSSZ");
ZonedDateTime zdt = ZonedDateTime.from(fmt.parse("25-12-2018 18:20:45.345+0800"));
System.out.println(zdt);
2018-12-25T18:20:45.345+08:00
Which date/time pattern we can use to format/parse?
Date and Time Patterns
Date and time formats are specified by date and time pattern strings. Refer to table below for some of the common date and time patterns used in DateTimeFormatter.
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
y | Year of era | year | 2018 ; 18 |
M | Month of year | number/text | 07 ; 7 ; July ; Jul
|
d | Day of month | number | 10 |
E | Day of week | text | Tuesday ; Tue ; T
|
a | Am/PM of day | text | PM |
H | Hour in day (0-23) | number | 0 |
h | clock hour of am/pm (1-12) | number | 12 |
m | Minute of hour | number | 30 |
s | Second of minute | number | 55 |
S | Millisecond (fraction of second) | number | 978 |
And some that we might not use that often:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G | Era | text | AD ; Anno Domini ; A |
Y | Week based year | year | 1998 ; 98 |
L | Month of year | number/text | 09 ; 9 |
w | Week of week based year | number | 27 |
W | Week of month | number | 2 |
D | Day of year | number | 189 |
F | Day of week in month | number | 2 |
k | Clock hour of day (1-24) | number | 24 |
K | Hour of am/pm (0-11) | number | 0 |
z | Time zone name | zone-name | Pacific Standard Time ; PST |
Z | Zone-offset | offset-Z | +0000 ; -0800 ; -08:00
|
x | zone-offset | offset-x | +0000 ; -08 ; -0830 ; -08:30 ; -083015 ; -08:30:15
|
Use ofPattern() method to get the format based on the pattern. For full format pattern, please check DateTimeFormatter documentation.
Following table showing some Java DateTimeFormatter date/time pattern with example. Current date in my laptop is 4 September 2019, 1 AM, Singapore Time (result may vary):
Date and Time Pattern | Result |
---|---|
"dd/MM/yy" | 04/09/19 |
"dd MMM yyyy" | 04 Sep 2019 |
"yyyy-MM-dd" | 2019-09-04 |
"dd-MM-yyyy h:mm a" | 04-09-2019 1:45 AM |
"dd-MM-yyyy hh:mm a, zzzz" | 04-09-2019 01:45 AM, Singapore Time |
"dd-MM-yyyy HH:mm:ss" | 04-09-2019 01:45:48 |
"yyyy-MM-dd HH:mm:ss.SSS" | 2019-09-04 01:45:48.616 |
"yyyy-MM-dd HH:mm:ss.SSSZ" | 2019-09-04 01:45:48.616+0800 |
"EEEE, dd MMMM yyyy HH:mm:ss.SSSZ" | Wednesday, 04 September 2019 01:45:48.616+0800
|
"yyMMddHHmmssSSS" | 190904014548616 |
And following are samples in different Date/Time classes (which implements TemporalAccessor):
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class DateTimeFormatterFormatExample {
static void print(String type, String result) {
System.out.printf("%s: %s\n", type, result);
}
public static void main(String[] args) {
// LocalDate
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd MMM yyyy");
print("LocalDate", formatter1.format(LocalDate.now()));
// LocalDateTime
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss a");
print("LocalDateTime", formatter2.format(LocalDateTime.now()));
// LocalTime
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("hh:mm:ss.SSS a");
print("LocalTime", formatter3.format(LocalTime.now()));
// OffsetDateTime
DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm a");
print("OffsetDateTime", formatter4.format(OffsetDateTime.now()));
// OffsetTime
DateTimeFormatter formatter5 = DateTimeFormatter.ofPattern("hh:mm:ss a xx");
print("OffsetTime", formatter5.format(OffsetTime.now()));
// ZonedDateTime
DateTimeFormatter formatter6 = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm a z");
print("ZonedDateTime", formatter6.format(ZonedDateTime.now()));
}
}
LocalDate: 04 Sep 2019 LocalDateTime: 04/09/2019 01:40:51 AM LocalTime: 01:40:51.161 AM OffsetDateTime: 09/04/2019 at 01:40 AM OffsetTime: 01:40:51 AM +0800 ZonedDateTime: 09/04/2019 at 01:40 AM SGT
Conclusion
The DateTimeFormatter class is used to both parse and format dates according to specified Date and Time Patterns. Use parse(...) method to convert from String to Date/Time classes, use format(...) method to convert from Date/Time into String.
If you not using Java 8 (and above), you can look at SimpleDateFormat.