簡體   English   中英

Java中可以使用什么日期時間格式來處理夏令時

[英]What Date time format can be used to handle DST in Java

我們的客戶在文本文件中以以下格式的字符串向我們發送開始和結束日期時間

2019-10-07 11:07 上午

所有日期時間都在一個時區。 我們計算開始和結束日期時間之間的差異來計算工作時間。 當夏令時轉換發生時,工作時間計算出錯。 他們沒有發送足夠的信息供我們正確計算。

我將建議他們向我們發送更多信息,以便我們解決此問題。 這里有什么好的解決方案? 我們應該向他們推薦哪種日期時間格式,以幫助我們解決 DST 更改並正確計算工作時間。

我們使用 Java。

做對並不明顯

他們告訴你他們的當地時間,你可以推斷出時區(因為“所有日期都在一個時區”)。

基本計算如下所示:

ZoneId pacific = ZoneId.of("America/Los_Angeles");
DateTimeFormatter local = DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm a").withZone(pacific);
ZonedDateTime start = ZonedDateTime.parse("2022-11-06 01:30 AM", local);
ZonedDateTime until = ZonedDateTime.parse("2022-11-07 01:30 AM", local);
long hours = start.until(until, ChronoUnit.HOURS);
System.out.printf("%d hours elapsed%n", hours);

這將打印“已過去25 小時”。 在太平洋時區,2022 年 11 月 6 日是 25 小時,因為秋季夏令時結束時,時鍾會撥慢一小時。 如果有人告訴您現在是凌晨 1:00,您不知道午夜是一小時前還是兩小時前。

默認偏移試探法

您真正需要的是偏移量,為此您必須依賴一些啟發式方法。 默認情況下, ZonedDateTime 通過選擇最早的偏移量(“夏季”偏移量)從多個不明確的本地日期時間中選擇一個時刻。

指定偏移量

如果這不是您想要的,您可以顯式覆蓋偏移量。 例如,也許你接近實時地處理這些時間戳,你可以根據當前時間猜出偏移量應該是多少。 或者您可能知道這些本地時間戳總是按時間順序處理; 通過跟蹤您看到的最晚時間,並注意后面是否有更早的時間戳,您可以檢測到時鍾撥回並更改偏移量。

ZonedDateTime.ofLocal()ZonedDateTime.ofStrict()函數可用於顯式控制偏移量。

偏移日期時間

或者,您可能會要求他們在時間戳字符串中包含偏移量。 通常這會用帶符號的小時數和分鍾數表示:“-07:00”或“-0800”。 這將在 DST 轉換期間提供明確的時間解釋。


這是使用OffsetDateTime的示例。 首先,如果偏移量使用冒號,如“2019-10-07T11:07:00+01:00”,這是一種標准格式,可以這樣解析:

OffsetDateTime start = OffsetDateTime.parse("2019-10-07T11:07:00+01:00");

如果缺少冒號,則需要格式化程序來處理非標准輸入:

DateTimeFormatter odt = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .appendOffsetId()
    .toFormatter();
OffsetDateTime when = OffsetDateTime.parse("2019-10-07T11:07:00+01:00", odt);

從那里開始,計算與ZonedDateTime相同:

OffsetDateTime start = OffsetDateTime.parse("2022-11-06T01:00:00-07:00", odt);
OffsetDateTime until = OffsetDateTime.parse("2022-11-07T01:54:00-08:00", odt);
long hours = start.until(until, ChronoUnit.HOURS);
System.out.printf("%d complete hours elapsed.%n", hours);
Duration duration = Duration.between(start, until);
System.out.println("Full duration: " + duration);

這是一個簡單的任務。 DateTimeFormatter class 為您提供所需的所有信息。 2019-10-07 11:07 AM 您的格式為'yyyy-MM-dd hh:mm a' ,您應該使用LocalDateTime class。但是由於您需要考慮夏令時,因此您可能需要使用類ZonedDateTimeOffsetDateTime並提供您的時區。 這可能有點矯枉過正,但我曾經參與過一個項目,我需要在事先不知道格式的情況下將字符串解析為日期。 所以,這是我寫的關於如何做到這一點的文章: Java 8 java.time package:解析任何字符串到日期

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM