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

How to convert UTC datetime to specific Zone datetime and check is daylight saving

例如,我有 UTC 日期时间

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

我想将其转换为特定时区 US/Eastern,然后我想检查转换后的 datetime 是否属于 DaylightSavings

时区

TimeZone.getTimeZone("US/Eastern");

夏令时代码

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

如果isDaylightSavings returns true 我必须将偏移量(-04:00)附加到输入dateTime

示例输出

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

如果 isDaylightSavings returns false 我必须将偏移量 (-05:00) 添加到输入 dateTime

示例输出

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

我有一些代码,但我很困惑如何将它们组合起来,最后一个问题

如何在 UTC 中生成电流 datetime f 不同区域的偏移量,例如考虑这个 US/Eastern

示例输出

dateTime = "2019-01-14T14:12:53-05:00"

正如评论中所说,这比您想象的更自动。

    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-04-23T15: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-23T14:50:53.236-05:00

编辑:

any idea how to remove milliseconds…

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

2018-04-23T15:50:53-04:00

(续)

…and this [America/New_York]

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

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

2018-04-23T15:50:53-04:00

如果19:50:53在东部时间,它会更简单一些:

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

2018-04-23T19:50:53.236-04:00

当前识别时区的方法是 region/city,所以我使用 America/New_York,尽管现在已弃用的 US/Eastern 仍然有效并产生相同的结果。

TimeZoneclass有设计问题,已经过时,被ZoneId取代,所以就用后者吧

Link: List of tz database time zones on Wikipedia