Wednesday, April 8, 2020

10 Examples to Format and Parse Date Time in Java 8 using LocalDateTime and DateTimeFormatter

Oracle Java Study Materials, Oracle Java Exam Prep, Oracle Java 8, Oracle Java Tutorial and Material

Parsing and formatting dates are other essential topics while working with date and time in Java. Even though old Date API had SimpleDateFormat and DateFormate class to support formatting of date and parsing texts, they were not simple, or should I say there were just simple in writing wrong code. You might know that SimpleDateFormat was not thread-safe and quite heavy to be used as a local variable. Thankfully, this has been sorted now with a new LocalDateTime class and DateTimeFormatter class, which has several inbuilt formatter, like BASIC_ISO_DATE format, which prints dates in yyyyMMdd format, like 20160616 and ISO_DATE which prints date as yyyy-MM-dd, like 2016-06-16. It has several useful formats to represent popular date formats around the world, like the date format used in the USA is different from than date format used in the UK and India.

Americans write the month before the day, like MM-dd-YY while British write day and the same British date format is also popular in India, like dd-MM-YYYY format.

The same date, 16th June 2016, will be written as 06-16-2016 in the United States and 16-06-2016 in Indian and England. Btw, that's not the end of it; there are several other date formats that are popular around the world as a Japanese write year first, e.g. yyyy-MM-dd or shortened one yy-MM-dd.

The built-in formats which can be used for both parsing text into a date and formatting date into text can be used to cover most of these popular date format around the world. It also allows you to specify your own custom date format.

The actual formatting and parsing work is done by the format() and parse() method of LocalDateTime class. This is a significant change in API, remember in old Date API, DateFormat class does both like it specifies the format and also provide parse() and format() method to carry out parsing and formatting.

10 Examples to Parse and Format Date in Java 8


This is an example-driven article, where you will see lots of how to format a date in Java. I also provide a little bit of commentary around the example to highlight essential details, e.g. you should be using "m" and not "M" while specifying formatting instruction for a month.

Well, the good thing about the new Date and Time API is that it has kept the formatting instruction the same as old API, so you don't need to learn it again.

The formatting instruction "yyyy-MM-dd" will produce 2016-06-16 with both new (LocalDateTime and DateTimeFormatter) and old Date and time API ((Date and SimpleDateFormat) in Java.

We'll first see examples of formatting dates into various date formats popular around the world, and then we'll learn how to parse the text to date by using the parse() method.

1. 1. Formatting in ISO Format

You can format a date into ISO date format, which is nothing but the yyyy-MM-dd format, i.e. it will print the current date as 2016-06-16, as shown in the following example.

String isoDate = now.format(DateTimeFormatter.ISO_DATE);
System.out.println("ISO date format: " + isoDate);

Output
ISO date format: 2016-06-16

This is an inbuilt formatter available in DateTimeFormatter class, its static as well, so just access it like we have done in this example. No need to specify any pattern.

1.2. Formatting LocalDateTime into BASIC_ISO_FORMAT

This is a close cousin of the previous example, the BASIC_ISO_FORMAT is nothing but yyyyMMdd format, e.g. 20160616, and this is also a built-in format, so you don't need to do anything, you can use call the format() method of LocalDateTime class and pass this formatter as shown in the following example:

String basicIsoDate = now.format(DateTimeFormatter.BASIC_ISO_DATE);
System.out.println("Basic ISO date format: " + basicIsoDate);

Output
Basic ISO date format: 20160616

1.3. Formatting Date in dd-MM-yyyy Format

The new Date and Time API not just provide built-in DateTimeFormatter but also allow you to create a custom one by specifying the pattern you want. In this example, we are creating a custom DateTimeFormatter patter to show dates in Indian date format, i.e. dd-MM-yyyy (16-06-2016). This is also the British date format, popular in England and some parts of the UK.

String indianDateFormat = now.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
System.out.println("formatting in Indian date format: " + indianDateFormat);

Output
formatting in Indian date format: 16-06-2016

1.4. How to format Date in Americal Date format

Well, the United States of America use different date format Britain. They put Month before Day i.e. American use MM-dd-yyyy format. You can again pass our USA date pattern to DateTimeFormatter.ofPattern() method and retreive a formatter to format date in american format as shown below:

DateTimeFormatter americanDateFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy");
String americanDate = now.format(americanDateFormat);
System.out.println("USA date format : " + americanDate);

Output
USA date format: 06-16-2016

The bottom line is as long as you understand the Date and Time formatting instruction, you can define any pattern to formate date.

Just make sure the pattern is valid and applicable to LocalDateTime class like using a pattern which contains timzone information with LocalDateTime will not work and throw following error at compile time:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
at java.time.LocalDate.get0(LocalDate.java:680)
at java.time.LocalDate.getLong(LocalDate.java:659)
at java.time.LocalDateTime.getLong(LocalDateTime.java:720)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$OffsetIdPrinterParser.format(DateTimeFormatterBuilder.java:3338)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1744)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1718)
at java.time.LocalDateTime.format(LocalDateTime.java:1746)
at test.Test.main(Test.java:65

The reason is apparent, there is no timezone information present in LocalDateTime. If you want to print data with timezone, then you should first convert LocalDateTimet to ZonedDateTime and then format it.

1.5. How to print date in Japanese DateFormat

Japanese use a different date format than the UK and USA; they put the year first followed by month and day. You can define both long and short date format for Japan using pattern "yyyy-MM-dd" and "yy-MM-dd" as shown in below example

DateTimeFormatter japan = DateTimeFormatter.ofPattern("yy-MM-dd");
String japanese = now.format(japan);
System.out.println("Date in Japan dateformat : " + japanese);

Output
Date in Japan date format: 16-06-16

1.6. Formatting LocalDateTime in ISO date time format

So far, we have only formatted LocalDateTime to date String, but since it doesn't contain time information, you can also format it into a String containing both date and time using DateTimeFormatter.ISO_DATE_TIME formatter, as shown below:

String isoDateTime = now.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println("Date in ISO date time format: " + isoDateTime);

Output
Date in ISO date time format: 2016-06-16T12:21:18.311

1.7. How to print Localized Date in Java

The DateTimeFormatter also allows you to create a format to represent a date in a localized format, e.g. in French, German, or any other format. For example, the month of June is called "juin" in French and if you want to print a date, e.g. 16. juin 2016, you need to let DatTimeFormatter know that you are interested in French locale.

You can do by using the overloaded version of DateTimeFormatter.ofPattern(pattern, local) method, which also accepts a Local as shown in the following example:

DateTimeFormatter french = DateTimeFormatter.ofPattern("d. MMMM yyyy",new Locale("fr"));
String frenchDate = now.format(French);
System.out.println("Date in french format: " + frenchDate);

Output
Date in french format: 16. juin 2016

You can see that Java has printed date in french format, "Jun" is written as "Juin," good stuff? No?

1.8. Formatting Date in Short Deutsche date/time formatting (06.16.16 12:07)

Here is one more example of the formatting date in Java 8 as per locale. This time we are printing date in short german date-time format, i.e. 06.16.116 12:07. We are using the same approach as the previous example with the only change that instead of passing our pattern, we are leveraging the built-in ofLocalizedDateTime() method to create a localized date format.

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
.withLocale(new Locale("de"));
String germanDateTime = now.format(formatter);
System.out.println("Date in short german format : " + germanDateTime);

Output
Date in short german format: 16.06.16 12:21

You use this approach to print dates in any other locale, as well.

1.9. How to format time in Java 8

So far, we have seen an example for formatting Date and DateTime, and now is a time to print formatted time in Java 8. Nothing changes except the DateTimeFormatter instance, this time, we'll use the DateTimeFormatter.ISO_TIME format, which prints time in HH:mm:ss:SSS format.

Here "s" is for a second, and "S" is for a millisecond. See the DateTimeFormat class for a full list of formatting instructions you can use to generate a pattern for formatting and parsing.

String isoTime = now.format(DateTimeFormatter.ISO_TIME);
System.out.println("time in ISO TIME format : " + isoTime);

Output
time in ISO TIME format : 12:21:18.311

1.10. Printing date in the long format in Java

Sometimes we need to print the date in an extended format, e.g. 16th June 2016. You can do so by using pattern dd-MMM-yyyy, the three M pattern will print the Month in three letters, e.g. "Jan", "Feb" or "Jun".

If you want the full name of the month, just use the "MMMM" pattern. The rest of the process is the same as the earlier example, you pass this pattern to static factory method ofPattern(), which return a corresponding DateTimeFormatter instance, which is used by LocalDateTime to convert a date in long format.

String longFormat = now.format(DateTimeFormatter.ofPattern("dd-MMM-yyyy"));
System.out.println("date in long format : " + longFormat);

Output
date in long format: 16-Jun-2016

2. How to print date with timezone in Java


Well, in order to format a datetime with timezone, you need a ZonedDateTime object, LocalDateTime is not sufficient as it doesn't contain timezone informtion. You can convert LocalDateTime to ZonedDateTime by providing ZoneId of any timezone you want e.g. "Europe/London" or "America/New_York". Once you an object of ZonedDateTime, just use the builtin ISO_ZONED_DATE_TIME formatter to print date with timezone in Java as done in following example:

ZonedDateTime dateWithTimeZone = ZonedDateTime.of(now, ZoneId.of("Europe/London"));
String withTimeZone = dateWithTimeZone.format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
System.out.println("date time with timezone : " + withTimeZone);

Output
date time with timezone : 2016-06-16T12:21:18.311+01:00[Europe/London]

If you don't follow the advice and try to format a LocalDatetime instance with ISO_ZONED_DATE_TIME ('2011-12-03T10:15:30Z') or RFC_1123_DATE_TIME (Tue, 3 Jun 2008 11:05:30 GMT'), you will get following error:

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds

which is obvious, because you don't have time zone related data.

3. How to parse the text to LocalDateTime in Java


Now that you know about how to format the date in Java, in which we create a formatted String from the LocalDateTime object, it's time to learn the other way, i.e. converting formatted String to Date in Java 8. All the knowledge you acquire about the date and time patterns while formatting is equally applicable here because you still need to create DateTimeFormatter of the pattern your date is, without that you cannot parse the text.

Another worth noting point is that all three key classes, e.g. LocalDate, LocalTime, and LocalDateTime, have parse() method, and they are overloaded two. The parse() method of LocalDate will parse the String by using ISO_LOCAL_DATE, e.g. "2016-06-16" and parse(DateTimeFormatter) will parse according to the pattern specified in that class. If the text is not valid as per the pattern, then ParseException will be thrown.

Similarly, LocalTime also has a parse() method to parse text into ISO_LOCAL_TIME format, and LocalDateTime also has a parse method convert String of ISO_LOCAL_DATETIME format.

Let's couple of examples of parsing Date String to LocalDate in Java 8:

LocalDate fromIsoDate = LocalDate.parse("2015-02-23");
LocalDate fromCustomPattern = LocalDate.parse("20-03-2017", DateTimeFormatter.ofPattern("dd-MM-yyyy"));
LocalDate invalidDate = LocalDate.parse("16-02-2018");

The first two is fine becuase the formatted String is a per the pattern specified by DateTimeFormatter but last one is invalid because date is in dd-MM-yyyy format as opposed to YYYY-MM-dd of ISO_DATE format, hence it will throw following error:

Exception in thread "main" java.time.format.DateTimeParseException: Text '16-02-2018' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947) at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.LocalDate.parse(LocalDate.java:400)
at java.time.LocalDate.parse(LocalDate.java:385)

Similarly, you can also parse text to LocalTime instance as shown below:

LocalTime fromIsoTime = LocalTime.parse("12:07:43.048");
LocalTime fromPattern = LocalTime.parse("11:06:32", DateTimeFormatter.ofPattern("HH:mm:ss"));

and you can do same with LocalDateTime or ZonedDateTime, if String contains the timezone information, you can convert it to ZonedDateTime instnace as well, as shown in following exmaple:

LocalDateTime fromIsoDateTime = LocalDateTime.parse("2016-06-16T13:12:38.954");
ZonedDateTime fromIsoZonedDateTime = ZonedDateTime.parse("2016-06-16T13:12:38.954+01:00[Europe/London]");

And here is the complete Java program to show you how to use LocalDateTime and DateTimeFormatter to format and parse dates in Java 8. If you want to learn more about Date-Time API and Java 8 in general, you can also check out The Complete Java MasterClass course on Udemy. One of the most up-to-date Java course which is also recently updated for Java 11.

Oracle Java Study Materials, Oracle Java Exam Prep, Oracle Java 8, Oracle Java Tutorial and Material

4. Java Program to format and parse Dates in JDK 8


Here is the complete sample program to demonstrate all the ways to format and parse date and time in JDK 8.

package test;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;

/**
 * Java Program to demonstrate how to use LocalDate, LocalTime, and
 * LocalDateTime in Java 8.
 */
public class Test {

  public static void main(String[] args) {

    // Formatting dates in Java 8
    LocalDateTime now = LocalDateTime.now();
   
    // Example 1 - print date as 2016-06-16 (yyyy-MM-dd)
    String isoDate = now.format(DateTimeFormatter.ISO_DATE);
    System.out.println("ISO date format: " + isoDate);
   
    // Example 2 - print date as 20160616 (yyyyMMdd)
    String basicIsoDate = now.format(DateTimeFormatter.BASIC_ISO_DATE);
    System.out.println("Basic ISO date format: " + basicIsoDate);
   
    // Example 3 - formatting date in British or Indian date format dd-MM-yyyy
    String indianDateFormat = now.format(DateTimeFormatter
        .ofPattern("dd-MM-yyyy"));
    System.out.println("formatting in Indian date format: " + indianDateFormat);
   
    // Example 4 - formatting date in USA date format (06-16-2016)
    DateTimeFormatter americanDateFormat = DateTimeFormatter
        .ofPattern("MM-dd-yyyy");
    String americanDate = now.format(americanDateFormat);
    System.out.println("USA date format : " + americanDate);
   
    // Example 5 - formatting in Japanese date format (16-06-16)
    DateTimeFormatter japan = DateTimeFormatter.ofPattern("yy-MM-dd");
    String japanese = now.format(japan);
    System.out.println("Date in Japan dateformat : " + japanese);
   
    // Example 6 - format in ISO date time format
    String isoDateTime = now.format(DateTimeFormatter.ISO_DATE_TIME);
    System.out.println("Date in ISO date time format: " + isoDateTime);
   
    // Example 7 - french date formatting 16. juin 2016
    DateTimeFormatter french = DateTimeFormatter.ofPattern("d. MMMM yyyy",
        new Locale("fr"));
    String frenchDate = now.format(french);
    System.out.println("Date in french format: " + frenchDate);
   
    // Example 8 - using short german date/time formatting (06.16.16 12:07)
    DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(
        FormatStyle.SHORT).withLocale(new Locale("de"));
    String germanDateTime = now.format(formatter);
    System.out.println("Date in short german format : " + germanDateTime);
   
    // Example 9 - formatting time in ISO_TIME format
    String isoTime = now.format(DateTimeFormatter.ISO_TIME);
    System.out.println("time in ISO TIME format : " + isoTime);
   
    // Example 10 - printing date in long format e.g. 16th June 2016
    String longFormat = now.format(DateTimeFormatter.ofPattern("dd-MMM-yyyy"));
    System.out.println("date in long format : " + longFormat);
   
    // Example 11 - formatting date with timezone
    ZonedDateTime dateWithTimeZone = ZonedDateTime.of(now,
        ZoneId.of("Europe/London"));
    String withTimeZone = dateWithTimeZone
        .format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
    System.out.println("date time with timezone : " + withTimeZone);
   
    // Parsing text to Date in Java 8
    LocalDate fromIsoDate = LocalDate.parse("2015-02-23");
    LocalDate fromCustomPattern = LocalDate.parse("20-03-2017",
        DateTimeFormatter.ofPattern("dd-MM-yyyy"));
    // LocalDate invalidDate = LocalDate.parse("16-02-2018");
   
    // parsing text to LocalTime in Java 8
    LocalTime fromIsoTime = LocalTime.parse("12:07:43.048");
    LocalTime fromPattern = LocalTime.parse("11:06:32",
        DateTimeFormatter.ofPattern("HH:mm:ss"));
   
    // converting String LocalDateTime and ZonedDateTime in Java 8
    LocalDateTime fromIsoDateTime = LocalDateTime
        .parse("2016-06-16T13:12:38.954");
    ZonedDateTime fromIsoZonedDateTime = ZonedDateTime
        .parse("2016-06-16T13:12:38.954+01:00[Europe/London]");

  }

}

Output
ISO date format: 2016-06-16
Basic ISO date format: 20160616
formatting in Indian date format: 16-06-2016
USA date format : 06-16-2016
Date in Japan dateformat : 16-06-16
Date in ISO date time format: 2016-06-16T13:14:40.948
Date in french format: 16. juin 2016
Date in short german format : 16.06.16 13:14
time in ISO TIME format : 13:14:40.948
date in long format : 16-Jun-2016
date time with timezone : 2016-06-16T13:14:40.948+01:00[Europe/London]

That's all about how to parse and format the date and time in Java. We've seen lots of examples to format LocalDateTime to various popular date-time formats around the world, e.g. the USA date format "yyyy-MM-dd" and the UK date format "dd-MM-yyyy" which is also popular in India. Wherever possible, use the built-in formatter from the DateTimeFormatter class. You also don't need to be worried about thread-safety because both LocalDateTime and DateTimeFormatter are immutable in Java 8.

Related Posts

0 comments:

Post a Comment