【问题标题】:How do I represent the "repeated" hour during the transition back to Standard time using JodaTime?如何使用 JodaTime 表示转换回标准时间期间的“重复”小时?
【发布时间】:2016-03-28 21:20:31
【问题描述】:

2016 年 11 月 6 日,将有两个 01-02 小时:

  • 01:00:00 - 01:59:59 然后是夏令时
  • 01:00:00 - 01:59:59 标准时间

标准时间可以这样表示:

private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

public void DoSomething() {
    DateTimeZone tz = DateTimeZone.forID("America/New_York");
    localDateTime = formatter.withZone(tz).parseDateTime("2016-11-06 02:01:00");
}

然而,在转换回标准时间之前的 01-02 小时内表示夏令时一直是一个挑战。与解析模糊时间相关的业务规则似乎是“默认为标准时间”:

//Ambiguous time, treated as Standard
DateTime ambiguousTime = formatter.withZone(tz).parseDateTime("2016-11-06 01:59:00");

我不确定如何覆盖此规则,并区分日光和标准。这是在 API 边界,我可以让客户提供几乎任何东西。我认为偏移量和时区应该足以消除这些极端情况下的歧义,这似乎是how NodaTime does it?

如果这是使用 Joda 时间执行此操作的“正确”方法,有人可以提供一个示例吗?如果有其他方法,我也愿意这样做。

【问题讨论】:

  • 不确定我是否理解,是的,您的时间不明确,因为您没有在字符串表示中指定时区。你怎么知道他们是纽约时间但不知道 UTC 偏移量?
  • IANA 时区 + 日期时间不足以确定一年中某一天两小时的准确瞬间:时钟从夏令时倒退到标准时间的那一天。想象一下,现在是 11 月 6 日凌晨 1:54,在 America/New_York。是 UTC-4 还是 UTC-5?没有更多信息你无法知道,因为第一次通过 1-2 小时,是 UTC-4,第二次通过,是 UTC-5。 (在 Spring 跳转期间,1-2 根本不存在。)我可以让客户在服务调用中提供它想要的那个时间的含义(-4 或 -5),但我不确定如何一旦我这样做了,就在 JT 中使用它。
  • 我相信有一个 fromUTC 方法?如果您知道偏移量,那么您可以使用它。但我会先尝试将偏移量添加到您的字符串中
  • 是的,这似乎是一种解决方法:添加偏移量作为输入时间的一部分确实可以表示日光(UTC-4)与标准(UTC-5)。如果不在解析器中包含偏移量,我无法找到使其可表示的方法。我想这很好,实际上。

标签: java datetime jodatime


【解决方案1】:

我无法找到一种方法来使夏令时可表示,除了通过格式化程序,将偏移量作为解析字符串的一部分。

这是一个例子。

private DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");

public void DoSomething() {
    String daylightWithOffset = "2016-11-06 01:56:00 -0400";
    DateTime daylightUnambiguous = formatter.withZone("America/New_York").parseDateTime(daylightWithOffset);
    System.out.println(daylightUnambiguous);    //2016-11-06T01:56:00.000-04:00

    String standardWithOffset = "2016-11-06 01:56:00 -0500";
    DateTime standardUnambiguous = formatter.withZone("America/New_York").parseDateTime(standardWithOffset);
    System.out.println(standardUnambiguous);    //2016-11-06T01:56:00.000-05:00
}

在幕后,它们都具有正确的 UTC 时间表示,并且它们都具有与之关联的正确时区 (America/New_York)。将它们显示为本地时间都显示01:56,这是预期和期望的行为。

【讨论】:

    猜你喜欢
    • 2012-09-06
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多