此测试通常全年通过,此时没有丢失小时或增加小时数。但是现在它令人讨厌。我们正在验证到期日期getExp()
,减去7天,在发布日期的{10}之内,getIss()
。由于exp
和iss
值是在彼此之后生成的,因此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);
答案 0 :(得分:4)
您唯一的解决方案是:
更改您的报告,以便使用UTC(即epoch unix时间),而不是基于本地时间。从技术角度来看,这是一个更好的解决方案,因为它是包括大多数共享服务器和数据源在内的全球标准;没有DST担心;并且您仍然可以让您的报告计算当地时间。
或者,查找或添加可靠的'dateadd'类型的功能,将夏令时考虑在内。
我一直很惊讶所有平台都没有内置的功能。当然,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是您首选的解决方案,因为准确性和标准化更直接。