簡體   English   中英

Java 8 的新 Java 日期時間 API 是否會處理 DST?

[英]Does Java 8's new Java Date Time API take care of DST?

我正在考慮使用新的java 8 Date Time API 我用谷歌搜索了一下,發現 jodaTime 是 Java 的不錯選擇,但仍然有興趣了解這個新 API 是如何工作的。

我將所有時間以 UTC 值存儲在我的數據存儲中,並將根據用戶的時區將它們轉換為本地時區特定值。 我可以找到許多展示如何使用新的 Java 日期時間 API 的文章。 但是我不確定 API 是否會處理 DST 更改? 或者我們有更好的處理 Date 的方法嗎?

我只是在學習新的 Date API ,所以想聽聽您對處理 DateTime 並根據用戶時區顯示它的想法。

這取決於您使用哪個類:

  • Instant是全球時間軸 (UTC) 上的一個瞬時點,與時區無關。
  • LocalDateLocalDateTime沒有時區的概念,但調用now()當然會給你正確的時間。
  • OffsetDateTime有一個時區,但不支持夏令時。
  • ZonedDateTime具有完整的時區支持。

它們之間的轉換通常需要一個時區,所以要回答你的問題:

是的,如果您使用得當,Java 8 日期/時間可以處理 DST。

安德烈亞斯的答案是正確的。

示例代碼

讓我們用一些代碼來測試一下。 美國和加拿大的夏令時將於今年 2015 年 11 月 1 日 02:00 到期。

讓我們從“本地”日期時間的凌晨 1 點開始,這意味着不受時間線限制並忽略時區問題。 再增加一個小時,我們就到了凌晨 2 點。 說得通。

LocalDateTime localDateTime = LocalDateTime.of( 2015 , Month.NOVEMBER , 1 , 1 , 0 ); // 1 AM anywhere. Not tied the timeline nor to any time zone.
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours( 1 ); // 2 AM anywhere, in no particular time zone, ignoring DST.

接下來我們得到具體的,具有特定的時區。 我們將凌晨 1 點帶到任何地方並將其放入America/Los_Angeles (美國西海岸)的時區。

ZoneId zoneId_LosAngeles = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime before = localDateTime.atZone( zoneId_LosAngeles ); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line.

現在增加一個小時,看看我們得到了什么。 如果忽略 DST,我們將得到凌晨 2 點。 如果遵守 DST,我們將得到凌晨 1 點……當到達凌晨 2 點時,掛鍾時間跳回到凌晨 1 點,但與 UTC 有新的偏移。 這在秋季(秋季)通俗地稱為“回退”

ZonedDateTime after = before.plusHours( 1 ); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015.

轉儲到控制台。

System.out.println( "localDateTime : " + localDateTime );
System.out.println( "localDateTimeOneHourLater : " + localDateTimeOneHourLater );
System.out.println( "before : " + before );
System.out.println( "after : " + after );

運行時,我們得到這個輸出。 沒有時區,凌晨 1 點 + 1 小時 = 凌晨 2 點。 請記住,這些是“本地”日期時間值,而不是 UTC 它們只代表日期時間的模糊概念,而不是時間線上的實際時刻。

localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00

但是在 DST 到期當天應用時區,我們得到不同的結果。 請注意一天中的時間如何保持01:00偏移量從 UTC更改為-07:00-08:00

before : 2015-11-01T01:00-07:00[America/Los_Angeles]
after : 2015-11-01T01:00-08:00[America/Los_Angeles]

如果我們調整到 UTC,這也許會更清楚、更容易驗證。 我們可以簡單地通過將beforeafter對象作為Instant對象訪問來做到這一點。 System.out.println然后隱式調用toString方法。

System.out.println( "before.toInstant : " + before.toInstant() );
System.out.println( "after.toInstant : " + after.toInstant() );

跑的時候。

before.toInstant : 2015-11-01T08:00:00Z
after.toInstant : 2015-11-01T09:00:00Z

Java 中的日期時間類型表,現代和傳統


關於java.time

java.time框架內置於 Java 8 及更高版本中。 這些類取代麻煩的老傳統日期時間類,如java.util.DateCalendar ,和SimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參閱Oracle 教程 並在 Stack Overflow 上搜索許多示例和解釋。 規范是JSR 310

您可以直接與您的數據庫交換java.time對象。 使用符合JDBC 4.2或更高版本的JDBC 驅動程序 不需要字符串,不需要java.sql.*類。

從哪里獲得 java.time 類?

ThreeTen-Extra項目用額外的類擴展了 java.time。 該項目是未來可能添加到 java.time 的試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

是的,Java API 將考慮 DST 更改。

本教程很好地解釋了如何在時區之間轉換日期以及如何選擇正確的類來表示日期: https : //docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

您還可以查看代表每個區域規則的類: http : //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html

特別是,此方法可以告訴您某個特定時刻是否處於夏令時: http : //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time 。立即的-

暫無
暫無

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

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