In Java:
long fromBytes = -8586803256090942249L;
// Mask out kind and ticks
int kind = Math.toIntExact((fromBytes >> 62) & 0x3);
long ticks = fromBytes & 0x3FFF_FFFF_FFFF_FFFFL;
LocalDateTime cSharpEpoch = LocalDate.of(1, Month.JANUARY, 1).atStartOfDay();
// 100 nanosecond units or 10^-7 seconds
final int unitsPerSecond = 10_000_000;
long seconds = ticks / unitsPerSecond;
long nanos = (ticks % unitsPerSecond) * 100;
LocalDateTime ldt = cSharpEpoch.plusSeconds(seconds).plusNanos(nanos);
switch (kind) {
case 0: // Unspecified
case 2: // Local time
System.out.println("Result LocalDateTime: " + ldt);
break;
case 1: // UTC
OffsetDateTime utcDateTime = ldt.atOffset(ZoneOffset.UTC);
System.out.println("Result OffsetDateTime in UTC: " + utcDateTime);
break;
default:
System.out.println("Not a valid DateTimeKind: " + kind);
break;
}
Output:
结果本地日期时间:2018-03-17T10:07:56.383355900
编辑:号码是
一个 64 位有符号整数,以 2 位编码 Kind 属性
字段和 62 位字段中的 Ticks 属性。
Tetsuya Yamamoto 是正确的,因为ticks 属性表示自 0001/01/01 一天开始(午夜)以来经过的 100 纳秒间隔数。类型为 0(表示未指定)、1(表示 UTC)或 2(表示本地时间)。所以我分别屏蔽了种类和蜱虫。
尽管在你的例子中,种类是 2,这应该是本地时间,但看起来时间确实是 UTC 时间。这是打印的时间与您预计的印度尼西亚西部时间下午 5:07:56 一致的唯一方法。也许该数字是在时区设置为 UTC 的计算机上生成的。
要获取您所在时区的时间:
ZoneId targetZone = ZoneId.of("Asia/Jakarta");
ZonedDateTime zdt = ldt.atZone(ZoneOffset.UTC).withZoneSameInstant(targetZone);
System.out.println("Converted to target time zone: " + zdt);
转换为目标时区:2018-03-17T17:07:56.383355900+07:00[亚洲/雅加达]
这与您在 C# 方面所说的一致。
PS 避免Date
如果可以的话,请使用 Java 中的类,它早已过时且设计不佳,多年前已被替换java.time,现代 Java 日期和时间 API https://docs.oracle.com/javase/tutorial/datetime/(我当然在上面使用了它)。如果您确实需要Date
对于您现在无法更改或不想更改的旧版 API,正如您在评论中已经指出的那样,转换如下:
Instant inst = ldt.atOffset(ZoneOffset.UTC).toInstant();
Date date = Date.from(inst);
System.out.println(date);
默认时区亚洲/雅加达的 JVM 上的输出:
3 月 17 日星期六 17:07:56 WIB 2018
致谢:Andreas 在一个答案(下面的链接)中解释了 64 位数字的结构,并给出了文档的链接。我把它们从那里带走了。
Links
-
DateTime.FromBinary(Int64) 方法 https://learn.microsoft.com/en-us/dotnet/api/system.datetime.frombinary?view=net-5.0来自 .NET 文档
- 安德烈亚斯对重复问题的回答 https://stackoverflow.com/a/65316086/5772882