如何在Java中指定夏令时后的时间

发布于 2025-01-13 19:01:32 字数 853 浏览 3 评论 0原文

使用以下代码:

class Test {
    public static void main(String [] args) {
        LocalDate date = LocalDate.of(2018, 11, 4);
        LocalTime time = LocalTime.of(1, 59);
        ZonedDateTime dt = ZonedDateTime.of(date, time, ZoneId.of("America/New_York"));
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(59);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
    }
}

我得到有

1:59:0
1:0:0
1:59:0
2:0:0

没有办法从夏令时之后到达 1:00:00 而无需经过夏令时之前的 1:00:00?

Using the following code:

class Test {
    public static void main(String [] args) {
        LocalDate date = LocalDate.of(2018, 11, 4);
        LocalTime time = LocalTime.of(1, 59);
        ZonedDateTime dt = ZonedDateTime.of(date, time, ZoneId.of("America/New_York"));
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(59);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
        dt = dt.plusMinutes(1);
        System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
    }
}

I get

1:59:0
1:0:0
1:59:0
2:0:0

Is there a way to get to the 1:00:00 from after daylight saving time without going through the 1:00:00 from before daylight saving time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜柠檬 2025-01-20 19:01:32

使用 ofStrict 指定您希望生成的分区日期时间处于哪个偏移量。 America/New_York 在相关时间附近从 -04:00 更改为 -05:00,因此您需要 ZoneOffset.ofHours(-5)

ZonedDateTime dt = ZonedDateTime.ofStrict(
    LocalDateTime.of(date, time), 
    ZoneOffset.ofHours(-5), 
    ZoneId.of("America/New_York")
);

如果您无法硬编码偏移量,则可以使用以下命令获取偏移量:

var dateTime = LocalDateTime.of(date, time)
var zone = ZoneId.of("America/New_York");
var offsetAfter = zone.getRules()
    .getTransition(dateTime)
    .getOffsetAfter();
ZonedDateTime dt = ZonedDateTime.ofStrict(
    dateTime, 
    offsetAfter, 
    zone
);

或者,正如 Ole VV 指出的那样,您也可以使用更短的:

ZonedDateTime dt = ZonedDateTime.of(
    date, time, ZoneId.of("America/New_York")
).withLaterOffsetAtOverlap();

Use ofStrict to specify which offset you want the resulting zoned date time to be on. America/New_York changes from -04:00 to -05:00 at around the time in question, so you want ZoneOffset.ofHours(-5).

ZonedDateTime dt = ZonedDateTime.ofStrict(
    LocalDateTime.of(date, time), 
    ZoneOffset.ofHours(-5), 
    ZoneId.of("America/New_York")
);

In case you cannot hardcode the offset in, you can get the offset after using:

var dateTime = LocalDateTime.of(date, time)
var zone = ZoneId.of("America/New_York");
var offsetAfter = zone.getRules()
    .getTransition(dateTime)
    .getOffsetAfter();
ZonedDateTime dt = ZonedDateTime.ofStrict(
    dateTime, 
    offsetAfter, 
    zone
);

Or, as Ole V.V. pointed out, you can also use the much shorter:

ZonedDateTime dt = ZonedDateTime.of(
    date, time, ZoneId.of("America/New_York")
).withLaterOffsetAtOverlap();
雪化雨蝶 2025-01-20 19:01:32

遵守夏令时的时区的问题是这样的时间不明确。 “America/New_York”区域有两个时间,均标记为 2008-11-04T01:00:00。从技术上讲,其中一个是 01:00 EDT,另一个是 01:00 EST,但没有很多软件可以让您以这种方式进行区分,尤其是因为这样的三字母时区名称不一定是全球唯一的。

解决方案是指定通用时间或相对于通用时间的时间,通用时间没有夏令时:第一个 01:00 东部时间为 05:00Z,第二个为 06:00Z。因此,您可以将时间指定为其中之一,并将区域指定为“UTC”(然后将结果转换为“America/New_York”),或者使用 ofStrict 指定相对于 UTC 的偏移量

The problem with time zones that honor Daylight Saving Time is that such times are ambiguous. The "America/New_York" zone has two times that are both labeled 2008-11-04T01:00:00. Technically, one of them is 01:00 EDT and the other is 01:00 EST, but not a lot of software will let you make the distinction that way, not least since such three-letter time zone designations are not necessarily globally unique.

The solution is to specify the time either in or relative to Universal time, which doesn't have daylight saving: the first 01:00 Eastern time is 05:00Z, and the second is 06:00Z. So you can either give the time as one of those and the zone as "UTC" (and then convert the result to "America/New_York"), or specify the offset from UTC using ofStrict.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文