使用 T 和 Z 將 LocalDate 格式化為 ISO 8601
1. 概述
在使用處理不同時區的應用程式或在系統之間交換資料時,以標準化格式處理日期和時間至關重要。
在本教程中,我們將探索將LocalDate
格式化為 ISO 8601 格式的各種技術。此格式包括「 T
」分隔符號和表示 UTC 時間的「 Z
」。
2. LocalDate
和 ISO 8601
LocalDate
是 Java 8 中java.time
套件下引入的現代日期和時間 API 的一部分。它是不可變的,這意味著一旦建立實例,其值就無法變更。它表示一個日期,不考慮時間或時區,只關注年、月和該月的日。 LocalDate
方便了日期資訊的操作和互動。
ISO 8601 是一項以清晰、明確且普遍接受的格式表示日期和時間的國際標準。它提供了一種表達日期和時間的標準化方法,這對於廣泛的應用至關重要。這包括資料交換、國際通訊和電腦系統。
ISO 8601 格式包含多個組成部分,最常見的格式是: YYYY-MM-DDThh:mm:ss.sssZ。
以下是組件的細分:
-
YYYY
:以四位數字表示年份(例如,2023) -
MM
:以兩位數字表示月份(例如,03 表示三月) -
DD
:以兩位數字表示月份中的第幾天(例如,15) - '
T
':將日期與時間分隔開的文字 'T
' 字符 -
hh
:以 24 小時格式表示一天中的小時(例如,14 表示下午 2 點) -
mm
:代表分鐘(例如,30) -
ss
:代表秒(例如,45) -
sss
:表示毫秒(可選且長度可能有所不同) - 「
Z
」:一個字面「Z
」字符,表示時間採用協調世界時 (UTC)
ISO 8601 允許使用各種可選組件,使其成為表示日期和時間資訊的通用標準。例如,我們可以包含時區偏移量,或在不相關時省略秒和毫秒。
「 Z
」字元表示時間採用 UTC 格式,但我們也可以透過指定與 UTC 的偏移量來表示本地時區的時間。
3.使用Java 8時間API
Java 提供了一種靈活的方法來格式化日期和時間對象,包括使用DateTimeFormatter
類的LocalDate
。
DateTimeFormatter
的實例是執行緒安全的,這使得它們適合在多執行緒環境中使用,而不需要外部同步。
以下是我們如何使用它將LocalDate
格式化為 ISO 8601:
class LocalDateToISO {
String formatUsingDateTimeFormatter(LocalDate localDate) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
String formattedDate = localDate.atStartOfDay().atOffset(ZoneOffset.UTC).format(formatter);
return formattedDate;
}
在此範例中,我們建立一個具有自訂模式的DateTimeFormatter
,其中在所需位置包含「 T
」和「Z」。然後,我們使用format()
方法將LocalDate
格式化為指定格式的字串。
我們可以執行測試來驗證其預期行為:
@Test
void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
String expected = "2023-11-06T00:00:00.000Z";
String actual = localDateToISO.formatUsingDateTimeFormatter(localDate);
assertEquals(expected, actual);
}
4.使用SimpleDateFormat
SimpleDateFormat
類別是用來格式化和解析日期的強大工具。它屬於java.text
包,提供了一種在文字表示形式和 Date 物件之間轉換日期的簡單方法。
它對於處理舊的日期時間類型(例如java.util.Date
特別有用。雖然它不像java.time
API 那麼現代或強大,但它仍然可以達到此目的:
String formatUsingSimpleDateFormat(LocalDate date) {
Date utilDate = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
String formattedDate = dateFormat.format(utilDate);
return formattedDate;
}
在上面的範例中,我們使用ZoneOffset.UTC
將LocalDate
轉換為ZonedDateTime
,然後將其轉換為Instant
物件。然後我們可以從Instant
中取得Date
物件並對該物件進行格式化。
讓我們使用SimpleDateFormat
格式化LocalDate
物件:
@Test
void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
String expected = "2023-11-06T00:00:00.000Z";
String actual = localDateToISO.formatUsingSimpleDateFormat(localDate);
assertEquals(expected, actual);
}
重要的是要意識到SimpleDateFormat
不是線程安全的。多個執行緒並發使用可能會導致意外結果或異常。為了解決這個問題,開發人員經常使用ThreadLocal
確保每個執行緒擁有其專用的SimpleDateFormat
實例。這有助於有效防止潛在的線程安全問題。
5. 使用 Apache Commons Lang3
Apache Commons Lang3 函式庫提供了一個名為FastDateFormat
的實用程式類,可簡化日期格式設定。它是SimpleDateFormat
的快速且線程安全的版本。在大多數格式化和解析場景中,我們可以直接用這個類別取代SimpleDateFormat
。事實證明,它在多執行緒伺服器環境中特別有用。
這種方法強調簡潔性,利用 Apache Commons Lang 3 的功能來創建清晰易懂的 Java 日期格式化程式碼。
我們可以透過包含以下相依性輕鬆地從中央 Maven 儲存庫取得該庫:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
安裝該庫後,我們可以使用它的方法。這是一個說明如何使用它的範例:
String formatUsingApacheCommonsLang(LocalDate localDate) {
Date date = Date.from(localDate.atStartOfDay().toInstant(ZoneOffset.UTC));
String formattedDate = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", TimeZone.getTimeZone("UTC"))
.format(date);
return formattedDate;
}
上面的程式碼範例採用LocalDate
,將其轉換為Date
,然後使用FastDateFormat
將其格式化為具有特定模式的字串,以將LocalDate
格式化為 ISO 8601。
讓我們繼續測試這個範例:
@Test
void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() {
LocalDateToISO localDateToISO = new LocalDateToISO();
LocalDate localDate = LocalDate.of(2023, 11, 6);
String expected = "2023-11-06T00:00:00.000Z";
String actual = localDateToISO.formatUsingApacheCommonsLang(localDate);
assertEquals(expected, actual);
}
6. 使用 Joda-Time
Joda-Time 是一個廣泛使用的 Java 函式庫,旨在解決java.util package
中原始日期和時間類別的缺點。在 Java 8 中的java.time
API 出現之前,Joda-Time 是處理日期和時間操作的流行且強大的替代方案。
為了整合 Joda-Time 庫的功能,我們應該在 pom.xml 中包含以下依賴項pom.xml:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
雖然在 Java 8 及更高版本中不再需要它,但它仍然是預先存在的程式碼庫的選項:
String formatUsingJodaTime(org.joda.time.LocalDate localDate) {
org.joda.time.format.DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
return formatter.print(localDate.toDateTimeAtStartOfDay(DateTimeZone.UTC));
}
在上面的範例中, Joda-Time
中的DateTimeFormatter
用於將LocalDate
格式化為 ISO 8601。
讓我們測試一下:
@Test
void givenLocalDate_whenUsingJodaTime_thenISOFormat() {
LocalDateToISO localDateToISO = new LocalDateToISO();
org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 11, 6);
String expected = "2023-11-06T00:00:00.000Z";
String actual = localDateToISO.formatUsingJodaTime(localDate);
assertEquals(expected, actual);
}
七、結論
在本文中,我們討論了在 Java 中使用「 T
」和「 Z
」將LocalDate
格式化為 ISO 8601 的不同方法。方法的選擇取決於我們對程式碼可讀性和可維護性的偏好。
我們可以選擇最適合我們需求的方法,並確保我們的日期和時間表示符合 ISO 8601 標準,以實現一致性和互通性。 DateTimeFormatter
方法更加靈活,適合處理各種格式要求,而其他方法則針對特定場景提供更簡單的解決方案。
與往常一樣,完整的源代碼可以 在 GitHub 上取得。