從 Java 中的日期時間字串取得日期和時間
一、簡介
使用日期和時間是許多 Java 應用程式中的常見任務。無論是解析輸入、格式化輸出或在程式中操作日期和時間,Java 都提供了強大的工具來有效地處理這些任務。通常,我們會收到需要操作的日期時間字串,例如分別提取日期和時間以進行進一步處理。
在本文中,我們將了解從輸入字串中單獨提取日期和時間的各種方法。
2. 理解問題
使用日期時間字串時最關鍵的一步是決定特定的格式。如果沒有標準格式,正確處理輸入字串幾乎是不可能的。因此,需要事先就格式達成一致。
在本教程中,我們將定義一個範例日期時間字串:
String datetime = "2024-07-04 11:15:24"
我們將使用格式yyyy-MM-dd HH:mm:ss作為預期標準。此外,我們將支援使用yyyy-MM-dd HH:mm:ss.SSS格式處理毫秒。
給定這個輸入字串,我們應該將其分成兩個字串: 2024-07-04和11:15:24 。
3. 使用split()
我們可以用空格分割輸入字串,並將日期和時間部分分開。我們看一下實作:
@Test
void givenDateTimeString_whenUsingSplit_thenGetDateAndTimeParts() {
String dateTimeStr = "2024-07-04 11:15:24";
String[] split = dateTimeStr.split("\\s");
assertEquals(2, split.length);
assertEquals("2024-07-04", split[0]);
assertEquals("11:15:24", split[1]);
}
這會將字串拆分為日期和時間部分。但是,請務必注意,此程式碼甚至會拆分無效字串,而不會指示有關日期時間字串有效性的任何錯誤。因此,可能會有更優雅的解決方案。
另一方面,如果日期和時間由空格分隔,此方法仍然可以分割任何輸入字串,使其適用於多種格式,而無需指定確切的模式。
讓我們來看另一個例子:
String dateTimeStr = "2024/07/04 11:15:24.233";
String[] split = dateTimeStr.split("\\s");
assertEquals(2, split.length);
assertEquals("2024/07/04", split[0]);
assertEquals("11:15:24.233", split[1]);
在上面的範例中,日期時間不遵循預期的模式。但是,我們仍然可以使用此方法,因為空格字元分隔日期和時間部分。
但是,如果字串中存在多個空格字符,則拆分會出錯。在這種情況下,我們可以使用帶有 limit 參數split() :
String dateTimeStr = "8/29/2011 11:16:12 AM";
String[] split = dateTimeStr.split("\\s", 2);
assertEquals(2, split.length);
assertEquals("8/29/2011", split[0]);
assertEquals("11:16:12 AM", split[1]);
在這裡,我們使用split()函數,限制為 2。即使日期時間字串中存在其他標記(例如 AM/PM),此方法也允許我們單獨提取日期和時間。
4. 使用DateTimeFormatter
分割日期和時間部分的另一種方法是使用java.time API。我們可以使用DateTimeFormatter將字串解析為LocalDateTime物件。之後,我們可以使用LocalDateTime物件上的方法來分離日期和時間部分。
讓我們來看一個例子:
String dateTimeStr = "2024-07-04 11:15:24";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH);
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, format);
assertEquals("2024-07-04", dateTime.toLocalDate().format(dateFormat));
assertEquals("11:15:24", dateTime.toLocalTime().format(timeFormat));
在本例中,我們使用輸入字串的預期模式建立了DateTimeFormatter的實例。然後我們可以使用格式化程式將字串解析為LocalDateTime 。之後,我們可以使用它的方法來檢索日期和時間組件。
與split()函數相比,此方法的優點是它允許我們驗證日期時間字串是否有效。然而,缺點是我們需要事先知道確切的模式,而split()方法可以在不事先知道確切格式的情況下處理多種格式。
讓我們探索改進此實現,以在驗證日期時間的同時支援多種格式。我們可以使用DateTimeFormatterBuilder來定義多種格式。這是一個例子:
DateTimeFormatter format1 = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss.SSS", Locale.ENGLISH);
DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder();
DateTimeFormatter multiFormatter = dateTimeFormatterBuilder
.appendOptional(format1)
.appendOptional(format2)
.toFormatter(Locale.ENGLISH);
// case 1
LocalDateTime dateTime1 = LocalDateTime.parse("2024-07-04 11:15:24", multiFormatter);
String date1 = dateTime1.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String time1 = dateTime1.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
assertEquals("2024-07-04", date1);
assertEquals("11:15:24", time1);
// case 2
LocalDateTime dateTime2 = LocalDateTime.parse("04-07-2024T11:15:24.123", multiFormatter);
String date2 = dateTime2.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String time2 = dateTime2.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
assertEquals("2024-07-04", date2);
assertEquals("11:15:24.123", time2);
在上面的程式碼範例中,我們利用DateTimeFormatterBuilder透過appendOptional()方法定義多種支援的格式。然後我們透過呼叫toFormatter()方法來獲得一個DateTimeFormatter實例。因此,我們使用這個格式化程式來解析輸入字串。這種方法使我們能夠輕鬆解析三種不同的格式。
但是,缺點是在轉換回單獨的日期和時間字串時,我們必須明確地提供確切的格式。
5. 使用正規表示式
我們也可以使用正規表示式來分別提取日期和時間分量。我們透過範例程式碼來看看正規表示式的用法:
String dateTimeStr = "2024-07-04 11:15:24.123";
Pattern pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s(\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?)");
Matcher matcher = pattern.matcher(dateTimeStr);
assertTrue(matcher.matches());
assertEquals("2024-07-04", matcher.group(1));
assertEquals("11:15:24.123", matcher.group(2));
在本例中,我們使用正規表示式來匹配並提取字串中的日期和時間部分。這種方法提供了處理各種格式的靈活性,但需要仔細的正規表示式製作。
六,結論
在本文中,我們探索了在 Java 中從日期時間字串中分離日期和時間組件的各種方法。我們介紹了簡單的字串拆分、使用DateTimeFormatter以及針對多種格式使用DateTimeFormatterBuilder 。此外,我們也討論了正規表示式的使用。每種方法都有優點和缺點,選擇取決於我們應用程式的要求和約束。
與往常一樣,本文中使用的範例程式碼可以 在 GitHub 上取得。