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

Parsing and formatting dates are other important 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 bad 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 new LocalDateTime class and DateTimeFormatter class, which has several inbuilt formatter e.g. BASIC_ISO_DATE format which prints dates in yyyyMMdd format e.g. 20160616 and ISO_DATE which prints date as yyyy-MM-dd e.g. 2016-06-16. It has several useful formats to represent popular date formats around the world e.g. the date format used in the USA is different than date format used in UK and India.

American write month before day e.g. MM-dd-YY while British write day and the same British date format is also popular in India e.g. 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 are popular around the world e.g. 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 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. You can further read The Complete Java MasterClass to learn more about new Date Time API of Java 8.




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 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 new Date and Time API is that it has kept the formatting instruction 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 format popular around the world and then we'll learn how to parse the text to date by using parse() method.


1. 1. Formatting in ISO Format

You can format a date into ISO date format which is nothing but 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 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 part of 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

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 obvious, there is no timezone information present in LocalDateTime. If you want to print date with timezone then you should first convert LocalDateTimet to ZonedDateTime and then format it. Don't worry, we'll see an example of formatting date with timezone later in this article. If you want to learn more, you can also see What's New in Java 8 course on Pluralsight.

 How to format Date in Americal Date format




1.5. How to print date in Japanese DateFormat

Japanese use a different date format than 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 date in 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 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 previous example with the only change that instead of passing our pattern we are leveraging 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 date 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 second and "S" is for a millisecond. See the DateTimeFormat class for a full list of formatting instruction 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 long 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 full name of the month just uses "MMMM" pattern. Rest of the process is 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

If you don't want dash in between, just remove the dash and introduce space. See Java SE 8 for Really Impatient by Cay S. Horstmann to learn more. One of the best books to learn Java 8.

How to print date with timezone in Java



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 pattern then ParseException will be thrown.

Similarly, LocalTime also has parse() method to parse text into ISO_LOCAL_TIME format and LocalDateTime also has 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.

 10 Examples of format and parse Dates in Java 8 using LocalDateTime and DateTimeFormatter



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 to parse and format date and time in Java. We've seen lots of examples to format LocalDateTime to various popular date time format 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 becuase both LocalDateTime and DateTimeFormatter are immutable in Java 8.

Further Reading
The Complete Java MasterClass
Java SE 8 for Really Impatient
From Collections to Streams in Java 8 Using Lambda Expressions


Related Java 8 Tutorials
If you are interested in learning more about new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8:

  • 5 Free Courses to learn Java 8 and Java 9 (courses)
  • 5 Books to Learn Java 8 from Scratch (books)
  • How to join String in Java 8 (example)
  • How to use filter() method in Java 8 (tutorial)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • How to use Stream class in Java 8 (tutorial)
  • How to convert List to Map in Java 8 (solution)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • How to use peek() method in Java 8 (example)
  • How to sort the map by keys in Java 8? (example)
  • How to sort the may by values in Java 8? (example)
  • 10 examples of Optional in Java 8? (example)
  • Difference between abstract class and interface in Java 8? (answer)
  • Top 5 Online Courses to Master Java 8 Concepts (courses)

Thanks for reading this article so far. If you like this article then please share with your friends and colleagues. If you have any question or feedback then please drop a comment.

P.S.: If you just want to learn more about new features in Java 8 then please see the course What's New in Java 8. It explains all the important features of Java 8 e.g. lambda expressions, streams, functional interfaces, Optional, new Date Time API and other miscellaneous changes.

No comments:

Post a Comment