【问题标题】:Convert time based on timezone using java.time使用 java.time 根据时区转换时间
【发布时间】:2015-06-16 15:52:58
【问题描述】:

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

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

【问题讨论】:

  • 表达式formatter.withZone(ZoneId.of("EST5EDT")); 没有用,因为您没有将它分配给DateTimeFormatter 的任何实例。请记住,此类是不可变的,因此所有更改只能通过复制来实现,而不是操作同一个实例。并且以这种方式设置时区不会影响解析为LocalDateTime(时区将被忽略)。

标签: java time java-8 java-time


【解决方案1】:

这个答案可能比 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

【讨论】:

    【解决方案2】:

    您不应该考虑“更改时区”LocalDateTime - LocalDateTime 没有时区。相反,您应该从 LocalDateTime 和时区 (ZoneId) 构建 ZonedDateTime。先去掉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));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2014-08-24
      • 1970-01-01
      • 2020-06-06
      • 2017-03-30
      • 2022-12-12
      • 1970-01-01
      相关资源
      最近更新 更多