Table of Contents
ToggleDateTimeFormatter 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 等方法。