当前位置: 首页 > 知识库问答 >
问题:

夏令时DST查找两个日期之间的差异

洪昱
2023-03-14

我们从外部来源发送两个日期作为字符串。然后我们计算日期之间的差异,看看它们工作了多少小时。

由于时间的变化,一年两次——我们的计算会出错。我们使用Java。你怎么解决这样的问题?

这两个日期以字符串形式出现在一个文件中,格式如下。“2019-10-07上午11:07”

共有2个答案

栾峰
2023-03-14

表示正确的时间点的一个好方法是ZonedDateTime,一旦构建了正确的时间点,就可以独立于任何假定的时区进行计算。这个类的优点在于,你可以使用自己对本地时间的概念轻松创建它的实例。你只需要告诉它你在哪个时区,它就会按照你所在时区的定义,在夏令时做正确的事情。一旦构建完成,就可以对这些对象执行日期/时间算法,而不必考虑时区或DST状态。

下面是两个简单的例子,用于创建和减去两个表示8小时时间跨度的ZoneDateTime对象,一个跨越DST更改,另一个不跨越DST更改。Java的日期函数很可能可以做到这一点,这样您就不必查看和处理单个数字。

案例1:工人工作8小时不超过DST点:

ZonedDateTime zdt = ZonedDateTime.of(
        2022, 1, 13, 1, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
ZonedDateTime zdt2 = ZonedDateTime.of(
        2022, 1, 13, 9, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
long hours = ChronoUnit.HOURS.between(zdt, zdt2);
System.out.println(hours);

结果:

8

案例2:工人工作8小时,跨越夏令时点:

ZonedDateTime zdt = ZonedDateTime.of(
        2022, 3, 13, 1, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
ZonedDateTime zdt2 = ZonedDateTime.of(
        2022, 3, 13, 10, 0, 0, 0, ZoneId.of("America/Los_Angeles"));
long hours = ChronoUnit.HOURS.between(zdt, zdt2);
System.out.println(hours);

结果:

8

请注意,如果你忘记了夏令时,你会认为第二个班次的工人多工作了一个小时。但是考虑到夏令时,两个班次的小时数是相同的。

注意:我从日期/时间的数字表示开始,因为问题没有给出示例,也没有指定所涉及的输入字符串的格式。一个涉及字符串解析的“正确”示例需要假定一种可能与OP开头的格式不同的格式。这里的主要问题是,时区是否以及如何在这些字符串中表示。解析一个字符串以得到一组数字和一个时区是一个单独的问题,与DST无关,所以我把这个问题留给OP来解决。很可能,您可以使用Java日期/时间库中的日期/时间解析逻辑直接获得ZonedDateTime,这同样取决于字符串的格式。

焦同
2023-03-14

这实际上取决于您的输入数据是什么,以及您试图确定的确切内容。

如果您只是接收日期,请将它们表示为LocalDate值——这就是LocalDate所表示的;没有任何关联时区的日期。例如,您可以使用Period.between来找出LocalDate值之间的差异。

然而,如果你想计算出两个时间瞬间之间经过的时间,那么你确实需要考虑时区——在这种情况下,你可以解析成OffsetDateTimezoneDateTime(或者直接Instant——这取决于你的输入数据)。使用持续时间,可以在任意两个时间值(例如OffsetDateTimeZonedDateTime,或Instant)之间找到经过的持续时间。介于之间。

值得注意的是,如果输入数据指定了一个时区(例如欧洲/伦敦)和一个本地日期/时间,则需要考虑不明确的本地日期/时间值。例如,假设文件如下所示:

Time zone: Europe/London
Shift 1 start: 2022-10-31T01:30
Shift 1 end: 2022-10-31T02:30

应该是一个小时还是两个小时?也可能是,因为当天欧洲/伦敦时区的凌晨1:30发生了两次,时钟从凌晨2点回到凌晨1点。你甚至可能会得到乍一看似乎难以置信的数据:

Time zone: Europe/London
Shift 1 start: 2022-10-31T01:30
Shift 1 end: 2022-10-31T01:15

如果它在第一次出现的1:30开始,在第二次出现的1:15结束,那么45分钟的轮班是完全有效的。

 类似资料:
  • 问题内容: 嗨,我正在使用jquery-uidatepicker选择date和date.js来查找两个日期之间的差异。 现在的问题是我想从计算中排除周末(周六和周日)。我该怎么办? 例如,用户选择开始日期(13/8/2010)和结束日期(16/8/2010)。由于14/8/2010和15/8/2010是工作日,而不是总共4天,所以我希望只有2天。 这是即时消息正在使用的代码: 问题答案: 也许其他

  • 问题内容: 我必须找到java中两个不同日期对象之间的时间差异,如果该时间超过5秒,我必须使会话无效。 这是场景: 我有一个jsp页面,它每5秒设置一次会话 我还有另一个jsp页面,每1秒访问一次, 现在,我必须在我提到的另一个jsp中进行比较,并使会话无效, 因此,如果差异超过5秒,则会话无效。 问题答案:

  • 问题内容: 我知道我可以使用momentjs做任何事情,还可以做一些涉及日期的事情。但是令人尴尬的是,我很难去做一件看起来很简单的事情:得到两次之间的差。 例: 我试过的 我不知道那里的“ 10”是什么。我住在巴西,所以如果相关的话,我们是utc-0300。 结果是持续时间正确的内部值: 所以,我想我的问题是:如何将momentjs持续时间转换为时间间隔?我肯定可以用 但我觉得有一些更 优雅 ,我

  • 问题内容: 我试图得到两个日期时间之间的差异,并将其作为返回。我找到了使用示例,但似乎无法正确处理。 但是登录到我的数据库。这是因为我没有格式化totaltime变量吗? 问题答案: 我不确定您要寻找的格式有何不同,但这是使用DateTime的方法

  • 问题内容: 如何使用PHP查找两个日期之间的天数? 问题答案:

  • 请让我知道这里出了什么问题。需要找出HH:MM:SS格式的不同之处。