Java 8 Format LocalDateTime Example
1. Introduction
Java 8 Date-time API provides a java.time.LocalDateTime class which is an immutable date-time object and often is viewed as a year-month-day-hour-minute-second format. It contains a java.time.format package to handle the formatting of dates and times. This package includes three classes:
DateTimeFormatter
– to print and parse date-time objects. It provides common formatting constants as well as a string pattern format.DateTimeFormatterBuilder
– to create a customized date-time format.DecimalStyle
– to localize the decimal style used in date and time formatting.
In this example, I will demonstrate how to format a LocalDateTime
object in five ways:
- Using predefined constants, such as
DateTimeFormatter.ISO_LOCAL_DATE
- Using String pattern letters, such as
yyyy-MM-dd
- Using localized decimal styles, such as
DecimalStyle.GERMAN
- Using predefined format styles, such as
FormatStyle.LONG
- Using a customized date format
2. Technologies used
The example code in this article was built and run using:
- Java 1.8.101
- Maven 3.3.9
- Eclipse Oxygen
- JUnit 4.12
3. Maven Project
3.1 Dependency
Add JUnit to the pom.xml.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>zheng.jcg.demo</groupId> <artifactId>java8-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
4. Custom Date Formattor
4.1 MaryDateFormatter
In this step, I will create a MaryDateFormatter
via DateTimeFormatterBuilder
to create a customized format for a local date time and a JUnit test class to show its usage.
MaryDateFormatter.java
package com.zheng.demo; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; public class MaryDateFormatter { static DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); public static DateTimeFormatter getMaryDateFormatter() { return builder.appendLiteral("Day is:").appendValue(ChronoField.DAY_OF_MONTH).appendLiteral(", Month is:") .appendValue(ChronoField.MONTH_OF_YEAR).appendLiteral(", Year is:").appendValue(ChronoField.YEAR) .appendLiteral(" with the time").appendText(ChronoField.HOUR_OF_DAY).appendLiteral(":") .appendValue(ChronoField.MINUTE_OF_HOUR).toFormatter(); } }
I will create a JUnit test class.
MaryDateFormatterTest.java
package com.zheng.demo; import java.time.LocalDateTime; import org.junit.Before; import org.junit.Test; public class MaryDateFormatterTest { private LocalDateTime now; @Test public void customizedDateFormatter() { String text = now.format(MaryDateFormatter.getMaryDateFormatter()); System.out.println("Mary Date formatted:" + text); } @Before public void setup() { now = LocalDateTime.now(); System.out.println("now:" + now); } }
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zheng.demo.MaryDateFormatterTest now:2018-12-24T15:42:54.969 Mary Date formatted:Day is:24, Month is:12, Year is:2018 with the time15:42 Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.272 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
5. JUnit Tests
I will create several JUnit tests to demonstrate how to format a local date time via a DateTimeFormattor
class.
5.1 DecimalStyleFormatTest
Java 8 DecimalStyle provides a decimal character based on locale. For example, Italy, Germany, and France use a comma (,) as a decimal character; US, China, and Japan use a period (.) as a decimal character.
In this step, I will create a DecimalStyleFormatTest
class to format a LocalDateTime
.
DecimalStyleFormatTest.java
package com.zheng.demo; import static org.junit.Assert.assertEquals; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DecimalStyle; import java.util.Locale; import org.junit.Before; import org.junit.Test; public class DecimalStyleFormatTest { private LocalDateTime now; private DateTimeFormatter formatter; private static String DECIMALSTYLE_PERIOD="DecimalStyle[0+-.]"; private static String DECIMALSTYLE_COMMA="DecimalStyle[0+-,]"; @Test public void decimalStyle_standard() { DateTimeFormatter stdFormatter = formatter.withDecimalStyle(DecimalStyle.STANDARD); assertEquals(DECIMALSTYLE_PERIOD, stdFormatter.getDecimalStyle().toString()); System.out.println("Standard:" + stdFormatter.format(now)); } @Test public void decimalStyle_us() { DateTimeFormatter usFormatter = formatter.withDecimalStyle(DecimalStyle.of(Locale.US)); assertEquals(DECIMALSTYLE_PERIOD, usFormatter.getDecimalStyle().toString()); System.out.println("US:" + usFormatter.format(now)); } @Test public void decimalStyle_german() { DateTimeFormatter germanFormatter = formatter.withDecimalStyle( DecimalStyle.of(Locale.GERMAN)); assertEquals(DECIMALSTYLE_COMMA, germanFormatter.getDecimalStyle().toString()); System.out.println("German:" + germanFormatter.format(now)); } @Test public void decimalStyle_italy() { DateTimeFormatter germanFormatter = formatter.withDecimalStyle( DecimalStyle.of(Locale.ITALY)); assertEquals(DECIMALSTYLE_COMMA, germanFormatter.getDecimalStyle().toString()); System.out.println("Italy:" + germanFormatter.format(now)); } @Test public void decimalStyle_france() { DateTimeFormatter germanFormatter = formatter.withDecimalStyle( DecimalStyle.of(Locale.FRANCE)); assertEquals(DECIMALSTYLE_COMMA, germanFormatter.getDecimalStyle().toString()); System.out.println("France:" + germanFormatter.format(now)); } @Test public void decimalStyle_china() { DateTimeFormatter germanFormatter = formatter.withDecimalStyle( DecimalStyle.of(Locale.CHINA)); assertEquals(DECIMALSTYLE_PERIOD, germanFormatter.getDecimalStyle().toString()); System.out.println("China:" + germanFormatter.format(now)); } @Before public void setup() { now = LocalDateTime.now(); formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; System.out.println("now:" + now); System.out.println("now with ISO_LOCAL_DATE_TIME:" + formatter.format(now)); System.out.println("Default decimalStyle:" + formatter.getDecimalStyle()); } @Test public void printOutAllAvailableLocalesDecimalStyle() { for (Locale localStyle : DecimalStyle.getAvailableLocales()) { DateTimeFormatter eFormatter = formatter.withDecimalStyle(DecimalStyle.of(localStyle)); System.out.println(localStyle.getDisplayName() + "-" + localStyle.toString() + "-DecimalStyle:" + eFormatter.withDecimalStyle(DecimalStyle.of(localStyle)).getDecimalStyle()); System.out.println("*********"); } } }
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zheng.demo.DecimalStyleFormatTest now:2018-12-24T15:41:20.148 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.148 Default decimalStyle:DecimalStyle[0+-.] US:2018-12-24T15:41:20.148 now:2018-12-24T15:41:20.221 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.221 Default decimalStyle:DecimalStyle[0+-.] Standard:2018-12-24T15:41:20.221 now:2018-12-24T15:41:20.221 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.221 Default decimalStyle:DecimalStyle[0+-.] China:2018-12-24T15:41:20.221 now:2018-12-24T15:41:20.232 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.232 Default decimalStyle:DecimalStyle[0+-.] Italy:2018-12-24T15:41:20,232 now:2018-12-24T15:41:20.236 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.236 Default decimalStyle:DecimalStyle[0+-.] France:2018-12-24T15:41:20,236 now:2018-12-24T15:41:20.239 now with ISO_LOCAL_DATE_TIME:2018-12-24T15:41:20.239 Default decimalStyle:DecimalStyle[0+-.] German:2018-12-24T15:41:20,239 Tests run: 7, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.201 sec Results : Tests run: 7, Failures: 0, Errors: 0, Skipped: 1
5.2 PredefinedFormatTest
DateTimeFormatter provides many formatting patterns to format a date. In this step, I will show it in JUnit test cases.
PredefinedFormatTest.java
package com.zheng.demo; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.junit.Before; import org.junit.Test; public class PredefinedFormatTest { private LocalDateTime now; private String dateString; @Test public void preDefinedConstant_BASIC_ISO_DATE() { dateString = now.format(DateTimeFormatter.BASIC_ISO_DATE); printOutDateString("BASIC_ISO_DATE"); } @Test public void preDefinedConstant_ISO_DATE() { dateString = now.format(DateTimeFormatter.ISO_DATE); printOutDateString("ISO_DATE"); } @Test public void preDefinedConstant_ISO_DATE_TIME() { dateString = now.format(DateTimeFormatter.ISO_DATE_TIME); printOutDateString("ISO_DATE_TIME"); } @Test public void preDefinedConstant_ISO_LOCAL_DATE() { dateString = now.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println("ISO_LOCAL_DATE"); } @Test public void preDefinedConstant_ISO_LOCAL_DATE_TIME() { dateString = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); System.out.println("ISO_LOCAL_DATE_TIME"); } @Test public void preDefinedConstant_ISO_ORDINAL_DATE() { dateString = now.format(DateTimeFormatter.ISO_ORDINAL_DATE); System.out.println("ISO_ORDINAL_DATE"); } @Test public void preDefinedConstant_ISO_WEEK_DATE() { dateString = now.format(DateTimeFormatter.ISO_WEEK_DATE); System.out.println("ISO_WEEK_DATE"); } @Before public void setup() { now = LocalDateTime.now(); System.out.println("now:" + now); } private void printOutDateString(String formatType) { System.out.println(formatType + ": " + dateString); } }
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zheng.demo.PredefinedFormatTest now:2018-12-24T15:45:41.067 ISO_ORDINAL_DATE now:2018-12-24T15:45:41.141 ISO_WEEK_DATE now:2018-12-24T15:45:41.142 ISO_LOCAL_DATE_TIME now:2018-12-24T15:45:41.144 ISO_LOCAL_DATE now:2018-12-24T15:45:41.145 ISO_DATE_TIME: 2018-12-24T15:45:41.145 now:2018-12-24T15:45:41.145 BASIC_ISO_DATE: 20181224 now:2018-12-24T15:45:41.146 ISO_DATE: 2018-12-24 Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.177 sec Results : Tests run: 7, Failures: 0, Errors: 0, Skipped: 0
5.3 LocalizedFormatTest
DateTimeFormatter provides four formatting styles to format a date. Unfortunately, there is a known bug for the Full
and Long
styles. In this step, I will show it in JUnit test cases.
LocalizedFormatTest.java
package com.zheng.demo; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import org.junit.Before; import org.junit.Test; public class LocalizedFormatTest { private LocalDateTime now; @Before public void setup() { now = LocalDateTime.now(); System.out.println("now:" + now); } @Test public void ofLocalizedDateTime_full_2() { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL); System.out.println("ofLocalizedDateTime_full:" + formatter.format(now)); } //see https://bugs.openjdk.java.net/browse/JDK-8085887 @Test(expected=Exception.class) public void ofLocalizedDateTime_full() { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL); System.out.println("ofLocalizedDateTime_full:" + now.format(formatter)); } @Test(expected=Exception.class) public void ofLocalizedDateTime_long() { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG); System.out.println("ofLocalizedDateTime_long:" + now.format(formatter)); } @Test public void ofLocalizedDateTime_medium() { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); System.out.println("ofLocalizedDateTime_medium:" + now.format(formatter)); } @Test public void ofLocalizedDateTime_short() { DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); System.out.println("ofLocalizedDateTime_short:" + now.format(formatter)); } }
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zheng.demo.LocalizedFormatTest now:2018-12-24T15:49:14.462 now:2018-12-24T15:49:14.533 now:2018-12-24T15:49:14.533 ofLocalizedDateTime_short:12/24/18 3:49 PM now:2018-12-24T15:49:14.534 now:2018-12-24T15:49:14.535 ofLocalizedDateTime_medium:Dec 24, 2018 3:49:14 PM Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.161 sec Results : Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
5.4 StringPatternFormatTest
DateTimeFormatter provides many string patterns to format a date. In this step, I will show it in JUnit test cases.
StringPatternFormatTest.java
package com.zheng.demo; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.junit.Before; import org.junit.Test; public class StringPatternFormatTest { private LocalDateTime now; @Before public void setup() { now = LocalDateTime.now(); System.out.println("now:" + now); } @Test public void stringPattern_1() { String text = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")); System.out.println("String formatted:" + text); } @Test public void stringPattern_2() { String str = "2018-12-21 12:30"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); LocalDateTime dateTime = LocalDateTime.parse(str, formatter); System.out.println("dateTime:" + dateTime); System.out.println("dateTime with formatter:" + dateTime.format(formatter)); } }
Output
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.zheng.demo.StringPatternFormatTest now:2018-12-24T15:50:43.471 String formatted:2018/12/24 15:50:43 now:2018-12-24T15:50:43.519 dateTime:2018-12-21T12:30 dateTime with formatter:2018-12-21 12:30 Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.154 sec Results : Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
6. Java 8 Format LocalDateTime – Summary
In this example, I demonstrated how to format a LocalDateTime
object with Java 8 DateTimeFormatter
‘s predefined format patterns as well as a customized date format.
7. Download the Source Code
This example consists of a Maven project which formats a LocalDateTime
object in several different ways.
You can download the full source code of this example here: Java 8 Format LocalDateTime Example