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


