将LDAP日期与纪元进行比较

时间:2017-06-25 11:54:55

标签: java date ldap datetime-comparison

我正在尝试计算LDAP accountExpires。 给定值是LDAP日期 - 自01/01/1601 00:00以来的纳秒数。

测试它是否确实在new Date()之后的最佳方法是什么?

1 个答案:

答案 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时间的定义也是如此,这不是我所知道的。