【问题标题】:How to convert UTC datetime to specific Zone datetime and check is daylight saving如何将 UTC 日期时间转换为特定区域日期时间并检查是否为夏令时
【发布时间】:2019-01-14 20:13:06
【问题描述】:

例如,我有 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 返回true,我必须将偏移量(-04:00) 附加到输入dateTime

样本输出

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

如果isDaylightSavings 返回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"

【问题讨论】:

  • 除非我遗漏了什么,将 utc 日期/时间转换为特定时区应该会自动应用夏令时规则,您只需要通过适当的格式化程序输出结果
  • 好的,你能告诉我怎么做吗?这对我来说不是很清楚@MadProgrammer
  • 您可以查看this blog 了解时区之间转换的示例
  • 谢谢先生,让我看看@MadProgrammer

标签: java datetime java-time


【解决方案1】:

正如在 cmets 中所说,这比你想象的更自动。

    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

编辑

知道如何删除毫秒......

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

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

(续)

……还有这个[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

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

TimeZone 类有设计问题,已经过时,替换为ZoneId,所以就用后者吧。

链接: List of tz database time zones on Wikipedia

【讨论】:

  • 知道如何删除毫秒和这个[America/New_York],我只需要这样2018-04-23T19:50:53-04:00
  • 我在底部添加了一个链接。在列表中,每个区域 ID 都被标记为规范、别名或已弃用,最右侧是具有相同语义的规范区域。
猜你喜欢
  • 2012-04-07
  • 2022-12-17
  • 2010-09-22
  • 2022-01-20
  • 2014-01-24
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 2016-06-17
相关资源
最近更新 更多