将 LDAP 日期与纪元进行比较

Compare LDAP date to epoch

我正在尝试计算 LDAP accountExpires。 给定值为 LDAP 日期 - 自 01/01/1601 00:00.

以来的纳秒数

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

最好的方法可能取决于您的精度要求。我建议

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 时间值,这会生成 2017-06-25T12:10:14ZInstant 并打印 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 日 UTC 以来 100 纳秒间隔的数量(1 纳秒 = 十亿分之一秒)。”

请注意,在 1601 年并不是每个人都同意日历,所以那一年的 1 月 1 日是模棱两可的。大多数计算机软件都采用公历,所以我想 LDAP 时间的定义也是如此,我不知道。