最好的方法可能取决于您的精度要求。我建议
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:14Z 的 Instant 并打印 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时间的定义也是如此,这不是我知道的。