我正在尝试计算LDAP accountExpires。
给定值是LDAP日期 - 自01/01/1601 00:00
以来的纳秒数。
测试它是否确实在new Date()
之后的最佳方法是什么?
答案 0 :(得分:2)
最好的方法可能取决于您的精度要求。我建议
private static final Instant ldapEpoch = LocalDateTime.of(1601, Month.JANUARY, 1, 0, 0)
.atOffset(ZoneOffset.UTC)
.toInstant();
然后
long ldapTime = 131_428_662_140_000_000L;
Instant convertedTime = ldapEpoch.plusMillis( ldapTime / 10_000L );
System.out.println(convertedTime.isAfter(Instant.now()));
使用我的示例LDAP时间值,这会产生Instant
2017-06-25T12:10:14Z
并打印false
,因为时间不是在当前时间之后。
由于您在问题中提到new Date()
,我认为Date
的精度就足够了,即毫秒。我真的很想做ldapEpoch.plusNanos(ldapTime * 100)
以保持完整的精度,但这会溢出Java long
数据类型,因此会得到错误的结果。如果您需要完全精确,... 编辑,正如Basil Bourque在评论中所建议的那样,切掉小数秒,在整秒内工作,然后加回你的小数秒:
Instant convertedTime = ldapEpoch.plusSeconds( ldapTime / 10_000_000L )
.plusNanos( ldapTime % 10_000_000L * 100L );
(我第一次展示的方式也有效,给出了相同的结果;但编辑后的版本可能对知道Java日期和时间API的读者更自然(并且可能会稍微好一点,但这几乎不可能临界)。)
为什么我想乘以100? LDAP, Active Directory & Filetime Timestamp Converter I found表示“时间戳是自1601年1月1日以来100纳秒间隔(1纳秒=十亿分之一秒)的数量。”
请注意,在1601年并非每个人都同意日历,所以那一年的1月1日是模棱两可的。大多数计算机软件都采用公历,所以我想LDAP时间的定义也是如此,这不是我所知道的。