如何更改 Java 的 ZonedDateTime 中的时区

How to change timezone in ZonedDateTime for Java

我的意思是这个。假设我有一个日期对象是 2018 年 5 月 1 日 12:00AM。我想创建一个 ZonedDateTime 对象,它是 2018 年 5 月 1 日 12:00AM 但属于另一个时区(比如 EST)。因为如果我将该日期对象传入 ZonedDateTime,它会将该日期对象视为 UTC(因此它会将其视为 2018 年 5 月 1 日,12:00AM GMT),并且我希望它保留该日期字段值但将 timzeone 更改为 EST(2018 年 5 月 1 日,12:00AM EST)。在 Java 中有没有办法做到这一点?

你需要的是 LocalDate:

    LocalDate date = LocalDate.of(2018, Month.MAY, 1);

这在所有时区都可以理解,并且永远不会是 5 月 1 日。这个名字和 java.time 中的其他 class 名字中的“本地”意思是“没有时区”。

如果你坚持ZonedDateTime,答案是withZoneSameLocal:

    ZonedDateTime zdt = date.atStartOfDay(ZoneOffset.UTC);
    ZonedDateTime inEst = zdt.withZoneSameLocal(ZoneId.of("Australia/Brisbane"));
    System.out.println(inEst);

输出:

2018-05-01T00:00+10:00[Australia/Brisbane]

不要依赖 EST 或其他三个和四个字母的时区缩写。例如,EST 是有歧义的(在北美和澳大利亚都使用)并且不是时区(使用不到一年的一半)。而是给出 region/city,例如 America/Atikokan.

如果“日期对象”是指过时的 java.util.Date class 的对象(如果可以,请避免使用它们,更喜欢 [=14= 中的现代 classes ]):

    Date oldfashionedDate = // …;

    OffsetDateTime dateTime = oldfashionedDate.toInstant().atOffset(ZoneOffset.UTC);
    if (! dateTime.toLocalTime().equals(LocalTime.MIDNIGHT)) {
        throw new IllegalStateException("java.util.Date was supposed to be at midnight in UTC but was " + dateTime);
    }
    LocalDate date = dateTime.toLocalDate();
    System.out.println(date);

输出:

2018-05-01