Core Java

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:

  1. Using predefined constants, such as DateTimeFormatter.ISO_LOCAL_DATE
  2. Using String pattern letters, such as yyyy-MM-dd
  3. Using localized decimal styles, such as DecimalStyle.GERMAN
  4. Using predefined format styles, such as FormatStyle.LONG
  5. 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.

Download
You can download the full source code of this example here: Java 8 Format LocalDateTime Example

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button