使用java.time基于时区转换时间

时间:2015-06-16 15:52:59

标签: java time java-8 java-time

如何根据 LocalDateTime 中的时区更改时间,这里我建立了一个时区为 EST 的日期,现在我需要找到 UTC 的相应时间。请帮我解决这个问题

String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
formatter.withZone(ZoneId.of("EST5EDT"));
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);

2 个答案:

答案 0 :(得分:12)

你不应该考虑"改变时区"一个LocalDateTime - 一个LocalDateTime没有拥有时区。相反,您应该从ZonedDateTime和时区(LocalDateTime)构建ZoneId。首先删除formatter.withZone调用,然后使用:

ZonedId zone = ZoneId.of("EST5EDT"); // Or preferrably "America/New_York"
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);

然后你可以将其转换为瞬间,或者可以使用:

ZonedDateTime utc = zoned.withZoneSameInstant(ZoneOffset.UTC);

例如:

import java.time.*;
import java.time.format.*;

public class Test {
    public static void main(String[] args) {
        String str = "16Jun2015_153556";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
        ZoneId zone = ZoneId.of("America/New_York");
        LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
        ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);

        // Both of these print 2015-06-16T19:35:56Z
        System.out.println(zoned.toInstant()); 
        System.out.println(zoned.withZoneSameInstant(ZoneOffset.UTC));
    }
}

答案 1 :(得分:7)

这个答案可能比Jon Skeet的正确答案更具结构性。在上面的评论中,我也指出不要忽视DateTimeFormatter的不变性,所以请始终将带有“with ...()”前缀的任何方法的结果赋给相同类型的变量。

// parsing your string input
// NO!!! timezone is needed in this step because LocalDateTime is just without timezone
String str = "16Jun2015_153556";
DateTimeFormatter formatter = 
    DateTimeFormatter.ofPattern("ddMMMuuuu_HHmmss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(str, formatter);

System.out.println(ldt); // your input as java.time-object: 2015-06-16T15:35:56

然后将本地日期时间分配给EST区域。使用IANA符号“America / New_York”比使用过时的“EST5EDT”(仅支持固定dst规则而没有任何历史原始偏移历史)更安全。

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));

最后,您将中间全局时间戳转换回偏移UTC + 00的本地日期时间,保留相同的物理时间:

LocalDateTime utc = zdt.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
System.out.println(utc); // 2015-06-16T19:35:56