代码之家  ›  专栏  ›  技术社区  ›  Ryuzaki L

如何将UTC日期时间转换为特定区域日期时间并检查是否为夏令时

  •  -1
  • Ryuzaki L  · 技术社区  · 7 年前

    例如,我有UTC日期时间

    String dateTime = "2018-04-23 19:50:53.236";
    

    我想把这个转换成特定的时区 US/Eastern ,然后我要检查转换后的 datetime 来了 DaylightSavings

    时区

    TimeZone.getTimeZone("US/Eastern");
    

    DaylightSavings代码

    ZoneId.of("US/Eastern")
      .getRules()
      .isDaylightSavings( 
          Instant.now() 
      )
    

    如果 isDaylightSavings 返回true必须附加偏移量 (-04:00) 输入 dateTime

    样本输出

    dateTime = "2018-04-23T19:50:53-04:00"
    

    如果 isdaylight节省 返回false必须附加偏移量 (-05:00) 输入 日期时间

    样本输出

    dateTime = "2018-04-23T19:50:53-05:00"
    

    我有一些代码,但我很困惑如何组合所有代码,以及最后一个问题

    如何产生电流 日期时间 F不同区域 UTC 例如,考虑使用偏移 美国/东方

    样本输出

    dateTime = "2019-01-14T14:12:53-05:00"
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Anonymous    7 年前

    正如评论中所说,这比你想象的更为自然。

        DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .toFormatter();
        ZoneId zone = ZoneId.of("America/New_York");
    
        String dateTime = "2018-04-23 19:50:53.236";
        ZonedDateTime usEasternTime = LocalDateTime.parse(dateTime, inputFormatter)
                .atOffset(ZoneOffset.UTC)
                .atZoneSameInstant(zone);
        String formattedDateTime = usEasternTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        System.out.println(formattedDateTime);
    

    输出为:

    2018年4月23日15:50:53.236-04:00

    您要求的补偿 -04:00 作为标准ISO 8601格式的一部分输出。时间输出是15:50:53,您要求19:50:53。我知道19:50:53是在UTC,在这个UTC时间,美国东部的时间是15:50:53或4个小时。

    如果我们在冬天约会,我们会 -05:00 一天中的时间比UTC时间少5小时:

        String dateTime = "2018-11-23 19:50:53.236";
    

    2018年11月23日14:50:53.236-05:00

    编辑 :

    知道如何去除毫秒_

        String formattedDateTime = usEasternTime.truncatedTo(ChronoUnit.SECONDS)
                .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    

    2018年4月23日15:50:53-04:00

    (续)

    艾斯和这个 [America/New_York]

    当你打印 ZonedDateTime ,区域ID也会打印出来。上面我使用一个内置的格式化程序来控制输出。另一种选择是转换为 OffsetDateTime :

        OffsetDateTime odt = usEasternTime.truncatedTo(ChronoUnit.SECONDS)
                .toOffsetDateTime();
        System.out.println(odt);
    

    2018年4月23日15:50:53-04:00

    如果19:50:53出现在东部时间,情况会简单一点:

        ZonedDateTime usEasternTime = LocalDateTime.parse(dateTime, inputFormatter)
                .atZone(zone);
    

    2018年4月23日19:50:53.236-04:00

    当前识别时区的方法是 地区/城市 所以我用 America/New_York 即使现在被否决了 US/Eastern 仍然有效并产生相同的结果。

    这个 TimeZone 类有设计问题,已过时,替换为 ZoneId ,所以只需使用后者。

    链接: List of tz database time zones on Wikipedia

    推荐文章