【问题标题】:Java - Zonedatetime - Without Daylight SavingJava - Zoneddatetime - 没有夏令时
【发布时间】:2018-08-07 13:37:17
【问题描述】:

我有一个返回年、月、日和小时的 DTO。因此,将 DTO 中的值传递给 ZonedDateTime.of 方法。在这里,时间是太平洋标准时间上午 10 点过去。因此,尝试将其转换为 UTC。

当月份为 5 时,它返回开始时间 17PM,当月份为 2 时,它返回开始时间为 18PM UTC。它正在考虑节约日光。无论月份如何,它都应该是世界标准时间晚上 18 点。有什么办法可以忽略这里的夏令时吗?

  TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");

  final ZonedDateTime jobStartDateTimeZ = ZonedDateTime.of(2017, 5, 1, 10,
                    0, 0, 0, tz.toZoneId());

  Instant startTime = jobStartDateTimeZ.withZoneSameInstant(ZoneOffset.UTC).toInstant();

  System.out.println("Start Time "+startTime);

我们使用旧系统,字符串将位于 DB 中的“America/Los_Angeles”中,并且可以有任何时区,例如“America/Bahia”。我们希望在任何时区都使用这种格式。

【问题讨论】:

  • 如果您不希望它遵守夏令时,请不要使用遵守夏令时的时区。 TimeZone.getTimeZone("GMT+8") 给出了一个固定的偏移量(即使看起来 + 是错误的)。
  • @AndyTurner 你能详细说明一下并将其转化为答案吗?

标签: java dst datetime-conversion zoneddatetime


【解决方案1】:

这可能是一个黑客;但它有效。

    ZoneId tz = ZoneId.of("America/Los_Angeles");
    final ZonedDateTime jobStartDateTimeZ = ZonedDateTime.of(2017, 5, 1, 10, 0, 0, 0, tz);
    Instant startTime = jobStartDateTimeZ.toInstant();
    // add summer time (DST)
    startTime = startTime.plus(tz.getRules().getDaylightSavings(startTime));
    System.out.println("Start Time " + startTime);

打印出来

开始时间 2017-02-01T18:00:00Z

这不取决于时区是美国/洛杉矶或太平洋/皮特凯恩,也不取决于使用夏令时 (DST) 的时区。如果在相关瞬间生效,它只是补偿夏季时间。如果没有夏令时,则添加 0。

顺便说一句,不要使用过时的 TimeZone 类。现代的ZoneId 是一个很好的替代品。无论如何,当您转换为Instant 时,也不需要withZoneSameInstant()

【讨论】:

  • 它工作得很好,如果时区字符串是“America/Los_Angeles”左右,我觉得这是正确的方法。希望这适用于不遵守夏令时的国家/地区。
猜你喜欢
  • 2018-07-06
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 2016-09-19
  • 2022-12-10
  • 2017-11-10
相关资源
最近更新 更多