小编典典

您如何用Java 8 Instant表示MS-DTYP`DATETIME`?

java

在Microsoft Spec中,DATETIME表示为2个32位整数:lowhigh

参考: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

所以高和低的计算

int high = (int)(fullval >> 32);
int low = (int)fullval;

那么高= 30333378 和低=552794112

如何将这些计算到Java 8 Instant?


阅读 300

收藏
2020-11-26

共1个答案

小编典典

对于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值是负数,我们应该抛出一个异常。

2020-11-26