由于夏令时,JWT发行日期与到期日期检查失败。什么是全年永久解决方案?

时间:2018-03-06 23:26:30

标签: java datetime time dst

此测试通常全年通过,此时没有丢失小时或增加小时数。但是现在它令人讨厌。我们正在验证到期日期getExp(),减去7天,在发布日期的{10}之内,getIss()。由于expiss值是在彼此之后生成的,因此10毫秒是一个完全可以接受的delta,可以预期值介于两者之间。

但现在,当Java日期代码在初始化新的JWT声明后调用setExp()时看起来一周后,它们可以理解为一小时。

断言/测试代码:

       assertThat(claim.getExp()).isCloseTo(new DateTime(claim.getIss()).plusDays(7).toDate(), 10);

在英文中,它写道:断言索赔的到期日期在索赔发行日期+7天之后的10毫秒内。

立即修复是为允许的增量添加一小时的毫秒数,但我很想知道是否有更好的解决方案。

编辑:我相信我发现了这个问题。我们使用ZonedDateTime.now()初始化索赔发布日期并声明到期日期:

Claim claim = new Claim();
claim.setIss(Date.from(ZonedDateTime.now(ZoneId.of("UTC")).toInstant())); 
claim.setExp(Date.from(ZonedDateTime.now(ZoneId.of("UTC")).plusDays(7).toInstant()));

但是当我们用JODA时间验证时,我们会假设夏令时的本地规则。这显然会导致GMT DST与美国DST规则的问题。

EDIT2:修复涉及2个单词并更新单元测试以尊重UTC:

    assertThat(claim.getExp()).isCloseTo(new DateTime(claim.getIss(), DateTimeZone.UTC).plusDays(7).toDate(), 10);

1 个答案:

答案 0 :(得分:4)

您唯一的解决方案是:

  1. 更改您的报告,以便使用UTC(即epoch unix时间),而不是基于本地时间。从技术角度来看,这是一个更好的解决方案,因为它是包括大多数共享服务器和数据源在内的全球标准;没有DST担心;并且您仍然可以让您的报告计算当地时间。

  2. 或者,查找或添加可靠的'dateadd'类型的功能,将夏令时考虑在内。

  3. 我一直很惊讶所有平台都没有内置的功能。当然,DST有一套令人困惑的,不断发展的规则,这些规则是针对特定地区的(按大陆,国家,有些地区是“州”,甚至是“县”)......但仍然如此。

    目前,在北美大部分地区,DST:

    • 在3月的第2个星期天开始。 (“Spring Forward”所以时钟从01:59变为03:00)

    • 结束在11月的第一个星期日。 (“退回”从01:59到01:00)

    Windows API具有计算DST是否生效的功能,但实际上,应用程序不允许应用程序显示,例如在北美:“2018年3月11日02:30:00”,因为那个时间不存在

    ......仍然,#1是您首选的解决方案,因为准确性和标准化更直接。