在Microsoft Spec中,DATETIME表示为2个32位整数:low和high
DATETIME
low
high
参考:https : //docs.microsoft.com/zh- cn/openspecs/windows_protocols/ms- dtyp/cca27429-5689-4a16-b2b4-9325d93e4ba2
FILETIME结构是一个64位值,表示自1601年1月1日(协调世界时)以来已过去的100纳秒间隔数。typedef struct _FILETIME {DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, PFILETIME, LPFILETIME; dwLowDateTime:32位无符号整数,包含文件时间的低位。dwHighDateTime:32位无符号整数,包含文件时间的高位。
例如,这是长 130280867040000000
130280867040000000
所以高和低的计算
int high = (int)(fullval >> 32); int low = (int)fullval;
那么高= 30333378 和低=552794112
30333378
552794112
如何将这些计算到Java 8 Instant?
对于1秒精度的转换,您自己的答案就可以了。如果您还需要转换秒的分数,这是一种方法。
Instant msFiletimeEpoch = Instant.parse("1601-01-01T00:00:00Z"); // a tick is 100 nanoseconds int nanosPerTick = 100; long ticksPerSecond = TimeUnit.SECONDS.toNanos(1) / nanosPerTick; long fullval = 130_280_867_040_000_000L; long seconds = fullval / ticksPerSecond; long nanos = fullval % ticksPerSecond * nanosPerTick; Instant answer = msFiletimeEpoch.plusSeconds(seconds).plusNanos(nanos); System.out.println(answer);
输出为:
2013-11-05T00:58:24Z
让我们尝试在原始价值上再加上1个勾号;它应该增加100纳秒。
long fullval = 130_280_867_040_000_001L;
2013-11-05T00:58:24.000000100Z
确实如此。
请注意未来很长的日期:根据您的报价,Microsoft整数都是无符号的。Java long已签名。因此,在30828年的某个时候,我们将开始获得非常错误的结果。万一如果long值是负数,我们应该抛出一个异常。
long