簡體   English   中英

Java ZonedDateTime和英國夏令時

[英]Java ZonedDateTime and British Summer Time

當日期在英國夏令時以內和以外時,我目前正在查看ZonedDateTime行為。

英國夏令時從3月25日開始,並且增加一小時(+1)。

我創建了幾個ZonedDateTime實例(UTC和Europe / London),接下來我將它們添加了1個月,以便它們屬於ZonedDateTime。

// These dates will be outside British Summer Time
ZonedDateTime utcFirstMarch = ZonedDateTime.of(2018, 3, 1, 12, 0, 0, 0, ZoneId.of("UTC"));
ZonedDateTime londonFirstMarch = ZonedDateTime.of(2018, 3, 1, 12, 0, 0, 0, ZoneId.systemDefault());

// These dates will be inside British Summer Time
ZonedDateTime utcFirstMarchPlusMonth = ZonedDateTime.of(2018, 3, 1, 12, 0, 0, 0, ZoneId.of("UTC")).plusMonths(1);
ZonedDateTime londonFirstMarchPlusMonth = ZonedDateTime.of(2018, 3, 1, 12, 0, 0, 0, ZoneId.systemDefault()).plusMonths(1);

ZonedDateTime londonFirstMarchPlusMonthToUtc = ZonedDateTime.of(2018, 3, 1, 12, 0, 0, 0, ZoneId.systemDefault()).plusMonths(1).withZoneSameInstant(ZoneId.of("UTC"));

這是我打印這些日期時的結果:

utcFirstMarch:                  2018-03-01T12:00Z[UTC]
londonFirstMarch:               2018-03-01T12:00Z[Europe/London]
utcFirstMarchPlusMonth:         2018-04-01T12:00Z[UTC]
londonFirstMarchPlusMonth:      2018-04-01T12:00+01:00[Europe/London]
londonFirstMarchPlusMonthToUtc: 2018-04-01T11:00Z[UTC]

最后,我為每個日期打印出了紀元秒:

utcFirstMarch:                  1519905600
londonFirstMarch:               1519905600
utcFirstMarchPlusMonth:         1522584000
londonFirstMarchPlusMonth:      1522580400
londonFirstMarchPlusMonthToUtc: 1522580400

我知道ZonedDateTime是不可變的。 這意味着當我添加一個月時,實際上創建了一個具有更改后的月的新實例。 您能告訴我我對給定觀察的假設是否正確:

  1. 加一個月將創建一個ZonedDateTime的新實例。 ZonedDateTime上的小時將始終相同。 新日期是否在BST中都沒有關系。 (查看LondonFirstMarch和LondonFirstMarchPlusMonth)

  2. 因為添加1個月后londonFirstMarchPlusMonth落入BST以使其仍為12:00,所以它實際上提取了一個小時。 這意味着基礎紀元秒將與utcFirstMarchPlusMonth不同。

  3. 最后,當我們將區域轉換為UTC時,londonFirstMarchPlusMonthToUtc顯示實際時間為11:00。

  4. 如果我想在1個月后再約會。 我應該只使用UTC,並可以選擇最后將其轉換為倫敦/歐洲?

編輯:

也許我還不夠清楚-道歉。 一個月是任意值,因此當添加到第一個日期時,產生的第二個日期屬於BST。

如前所述,一個月也許不是一個很好的例子,因為它意味着不同的情況,具體取決於我們所處的月份。對我來說,“月”將由24小時制組成。 (正如Ole.vv所說)

我認為以UTC時間運行並有選擇地將其轉換為歐洲/倫敦是解決“我的問題”的方法

您的假設通常是正確的。 一些評論。

對於1., ZonedDateTime將嘗試保持小時不變。 只有在不可能的情況下,它才會做其他事情。 例如,可能期望以下內容打印時間01:30:

    System.out.println(ZonedDateTime
            .of(2018, 2, 25, 1, 30, 0, 0, ZoneId.of("Europe/London"))
            .plusMonths(1));

它打印

2018-03-25T02:30+01:00[Europe/London]

在過渡到夏令時的時間向前移動1至凌晨2點,所以沒有那一天1:30時。 ZonedDateTime不會產生不存在的時間,因此在這種情況下,它將選擇02:30。

對於4.,“精確地一個月”很難精確定義,因為一個月可能是28、29、30或31天。 但是,如果您想使用24小時的倍數,則使用UTC即可。

我建議您將Period實例用於DateFormat正確行為:

ZonedDateTime nZoneDateTime = utcFirstMarch.plus(Period.ofDays(30));               

暫無
暫無

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

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