DateTimeFormatter in Java with Examples - Java 147

DateTimeFormatter in Java with Examples – Java 147

DateTimeFormatter in Java with Examples

提供了格式化日期時間的 API ,格式化 TemporalAccessor 類別,為日期、時間和偏移物件的基本接口,用來顯示及解析日期時間物件,是執行緒安全且不可變的,DateTimeFormatter in Java 介紹常見的 formatTo 、 parse 等方法,本篇增加了範例,並透過單元測試來驗證產出結果。

檔案目錄

./
   +- src
       +- test
       |   +- org
       |       +- ruoxue
       |           +- java_147
       |               +- datetime
       |                   +- datetimeformatter
       |                       +- DateTimeFormatterWithExamplesTest.java   

單元測試

DateTimeFormatter Java 提供自定義的日期時間樣版,格式化等操作 DateTimeFormatter 。

formatTo

建立一個 DateTimeFormatter ,格式化指定日期時間,將結果輸出到實作 Appendable 的類別。

	@Test
	public void formatTo() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		StringBuffer result = new StringBuffer("LocalDateTime: ");
		formatter.formatTo(LocalDateTime.now(), result);
		System.out.println(result);

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		result = new StringBuffer("LocalDate: ");
		formatter.formatTo(LocalDate.now(), result);
		System.out.println(result);

		formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
		result = new StringBuffer("LocalTime: ");
		formatter.formatTo(LocalTime.now(), result);
		System.out.println(result);
	}
LocalDateTime: 2023-06-27T13:18:55
LocalDate: 2023-06-27
LocalTime: 13:18:55

parsePosition

DateTimeFormatter Java 建立一個 DateTimeFormatter ,從指定位址開始,解析字串為日期時間。

	@Test
	public void parsePosition() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS");
		String value = "LocalDateTime: 2023-03-14T09:08:07.123456789";
		TemporalAccessor result = formatter.parse(value, new ParsePosition(15));
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14T09:08:07.123456789", result.toString());

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		value = "LocalDate: 2023-03-14";
		result = formatter.parse(value, new ParsePosition(11));
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14", result.toString());

		formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
		value = "LocalTime: 09:08:07.123";
		result = formatter.parse(value, new ParsePosition(11));
		System.out.println(result);
		assertEquals("{},ISO resolved to 09:08:07.123", result.toString());
	}
{},ISO resolved to 2023-03-14T09:08:07.123456789
{},ISO resolved to 2023-03-14
{},ISO resolved to 09:08:07.123

parseBest

DateTimeFormatter Java 建立一個 DateTimeFormatter ,解析字串為日期時間。

	@Test
	public void parseBest() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd['T'HH:mm:ss[Z]]");
		String value = "2023-03-14";
		@SuppressWarnings("rawtypes")
		TemporalQuery[] tmporalQuerys = new TemporalQuery[] { OffsetDateTime::from, LocalDateTime::from,
				LocalDate::from };
		TemporalAccessor result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14", result.toString());

		value = "2023-03-14T09:08:07";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07", result.toString());

		value = "2023-03-14T09:08:07+0000";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07Z", result.toString());

		value = "2023-03-14T09:08:07+0200";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07+02:00", result.toString());
	}
LocalDate: 2023-03-14
LocalDateTime: 2023-03-14T09:08:07
OffsetDateTime: 2023-03-14T09:08:07Z
OffsetDateTime: 2023-03-14T09:08:07+02:00

parseBestNano

DateTimeFormatter Java 建立一個 DateTimeFormatter ,解析字串為日期時間。

	@Test
	public void parseBestNano() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd['T'HH:mm:ss[.SSSSSSSSS][Z]]");
		String value = "2023-03-14";
		@SuppressWarnings("rawtypes")
		TemporalQuery[] tmporalQuerys = new TemporalQuery[] { ZonedDateTime::from, LocalDateTime::from, LocalDate::from,
				LocalTime::from };
		TemporalAccessor result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14", result.toString());

		value = "2023-03-14T09:08:07";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07", result.toString());

		value = "2023-03-14T09:08:07.123456789+0000";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07.123456789Z", result.toString());

		value = "2023-03-14T09:08:07.123456789+0200";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07.123456789+02:00", result.toString());
	}
LocalDate: 2023-03-14
LocalDateTime: 2023-03-14T09:08:07
ZonedDateTime: 2023-03-14T09:08:07.123456789Z
ZonedDateTime: 2023-03-14T09:08:07.123456789+02:00

parseUnresolved

Java DateTimeFormatter 建立一個 DateTimeFormatter ,當無法解析字串為日期時間時,傳回日期時間資訊。

	@Test
	public void parseUnresolved() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		String value = "LocalDateTime: 2023-00-99T88:77:66";
		TemporalAccessor result = formatter.parseUnresolved(value, new ParsePosition(0));
		System.out.println(result);
		assertNull(result);

		value = "LocalDateTime: 2023-00-99T88:77:66";
		result = formatter.parseUnresolved(value, new ParsePosition(15));
		System.out.println(result);
	}
null
{HourOfDay=88, MinuteOfHour=77, MonthOfYear=0, SecondOfMinute=66, YearOfEra=2023, DayOfMonth=99},null

parsedExcessDays

Java DateTimeFormatter 建立一個 DateTimeFormatter ,解析多餘天數。

	@Test
	public void parsedExcessDays() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
		String value = "24:00:00";
		TemporalAccessor temporalAccessor = formatter.parse(value);
		System.out.println(temporalAccessor);
		Period result = temporalAccessor.query(DateTimeFormatter.parsedExcessDays());
		System.out.println(result);
		assertEquals("P1D", result.toString());

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		value = "2023-03-14T24:00:00";
		temporalAccessor = formatter.parse(value);
		System.out.println(temporalAccessor);
		result = temporalAccessor.query(DateTimeFormatter.parsedExcessDays());
		System.out.println(result);
		assertEquals("P0D", result.toString());
	}
{},ISO resolved to 00:00
P1D
{},ISO resolved to 2023-03-15T00:00
P0D

parsedLeapSecond

Java DateTimeFormatter 建立一個 DateTimeFormatter ,解析是否為閏秒。

	@Test
	public void parsedLeapSecond() {
		TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse("2017-12-31T23:59:60Z");
		boolean result = temporalAccessor.query(DateTimeFormatter.parsedLeapSecond());
		System.out.println(result);
		assertTrue(result);
		
		temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse("2018-12-31T23:59:59Z");
		result = temporalAccessor.query(DateTimeFormatter.parsedLeapSecond());
		System.out.println(result);
		assertFalse(result);
	}
true
false

DateTimeFormatterWithExamplesTest.java

DateTimeFormatter in Java 新增單元測試,驗證 Java DateTimeFormatter Example 是否符合預期。

package org.ruoxue.java_147.datetime.datetimeformatter;

import static org.junit.Assert.*;

import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQuery;

import org.junit.Test;

public class DateTimeFormatterWithExamplesTest {

	@Test
	public void formatTo() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		StringBuffer result = new StringBuffer("LocalDateTime: ");
		formatter.formatTo(LocalDateTime.now(), result);
		System.out.println(result);

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		result = new StringBuffer("LocalDate: ");
		formatter.formatTo(LocalDate.now(), result);
		System.out.println(result);

		formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
		result = new StringBuffer("LocalTime: ");
		formatter.formatTo(LocalTime.now(), result);
		System.out.println(result);
	}

	@Test
	public void parse() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS");
		TemporalAccessor result = formatter.parse("2023-03-14T09:08:07.123456789");
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14T09:08:07.123456789", result.toString());

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		result = formatter.parse("2023-03-14");
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14", result.toString());

		formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
		result = formatter.parse("09:08:07.123");
		System.out.println(result);
		assertEquals("{},ISO resolved to 09:08:07.123", result.toString());
	}

	@Test
	public void parsePosition() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS");
		String value = "LocalDateTime: 2023-03-14T09:08:07.123456789";
		TemporalAccessor result = formatter.parse(value, new ParsePosition(15));
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14T09:08:07.123456789", result.toString());

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		value = "LocalDate: 2023-03-14";
		result = formatter.parse(value, new ParsePosition(11));
		System.out.println(result);
		assertEquals("{},ISO resolved to 2023-03-14", result.toString());

		formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
		value = "LocalTime: 09:08:07.123";
		result = formatter.parse(value, new ParsePosition(11));
		System.out.println(result);
		assertEquals("{},ISO resolved to 09:08:07.123", result.toString());
	}

	@Test
	public void parseBest() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd['T'HH:mm:ss[Z]]");
		String value = "2023-03-14";
		@SuppressWarnings("rawtypes")
		TemporalQuery[] tmporalQuerys = new TemporalQuery[] { OffsetDateTime::from, LocalDateTime::from,
				LocalDate::from };
		TemporalAccessor result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14", result.toString());

		value = "2023-03-14T09:08:07";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07", result.toString());

		value = "2023-03-14T09:08:07+0000";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07Z", result.toString());

		value = "2023-03-14T09:08:07+0200";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07+02:00", result.toString());
	}

	@Test
	public void parseBestNano() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd['T'HH:mm:ss[.SSSSSSSSS][Z]]");
		String value = "2023-03-14";
		@SuppressWarnings("rawtypes")
		TemporalQuery[] tmporalQuerys = new TemporalQuery[] { ZonedDateTime::from, LocalDateTime::from, LocalDate::from,
				LocalTime::from };
		TemporalAccessor result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14", result.toString());

		value = "2023-03-14T09:08:07";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07", result.toString());

		value = "2023-03-14T09:08:07.123456789+0000";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07.123456789Z", result.toString());

		value = "2023-03-14T09:08:07.123456789+0200";
		result = formatter.parseBest(value, tmporalQuerys);
		System.out.println(result.getClass().getSimpleName() + ": " + result);
		assertEquals("2023-03-14T09:08:07.123456789+02:00", result.toString());
	}

	@Test
	public void parseUnresolved() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		String value = "LocalDateTime: 2023-00-99T88:77:66";
		TemporalAccessor result = formatter.parseUnresolved(value, new ParsePosition(0));
		System.out.println(result);
		assertNull(result);

		value = "LocalDateTime: 2023-00-99T88:77:66";
		result = formatter.parseUnresolved(value, new ParsePosition(15));
		System.out.println(result);
	}

	@Test
	public void parsedExcessDays() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
		String value = "24:00:00";
		TemporalAccessor temporalAccessor = formatter.parse(value);
		System.out.println(temporalAccessor);
		Period result = temporalAccessor.query(DateTimeFormatter.parsedExcessDays());
		System.out.println(result);
		assertEquals("P1D", result.toString());

		formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
		value = "2023-03-14T24:00:00";
		temporalAccessor = formatter.parse(value);
		System.out.println(temporalAccessor);
		result = temporalAccessor.query(DateTimeFormatter.parsedExcessDays());
		System.out.println(result);
		assertEquals("P0D", result.toString());
	}

	@Test
	public void parsedLeapSecond() {
		TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse("2017-12-31T23:59:60Z");
		boolean result = temporalAccessor.query(DateTimeFormatter.parsedLeapSecond());
		System.out.println(result);
		assertTrue(result);
		
		temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse("2018-12-31T23:59:59Z");
		result = temporalAccessor.query(DateTimeFormatter.parsedLeapSecond());
		System.out.println(result);
		assertFalse(result);
	}
}

心得分享

Java DateTimeFormatter Example 預先定義的日期時間樣版,支援了多種遵循 ISO 和 RFC 標準,提供了幾種 DateTimeFormatter 常見方法的操作範例,在應用上相當廣泛,熟悉 Java DateTimeFormatter 這些方法的操作,像是: formatTo 、 parse 等方法。

發佈留言