1 回答
TA贡献1829条经验 获得超6个赞
在 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;
}
输出:
结果 LocalDateTime: 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# 方面的内容一致。
PSDate如果可以,请避免使用Java 中的类,它早已过时且设计不佳,多年前被java.time 取代,现代 Java 日期和时间 API(我当然在上面使用过)。如果您确实需要一个Date无法更改或不想更改的遗留 API,正如您在评论中已经指出的,转换是这样的:
Instant inst = ldt.atOffset(ZoneOffset.UTC).toInstant();
Date date = Date.from(inst);
System.out.println(date);
带有默认时区 Asia/Jakarta 的 JVM 上的输出:
2018 年 3 月 17 日星期六 17:07:56 WIB
致谢: Andreas 在回答(链接如下)中解释了 64 位数字的结构并提供了文档链接。我从那里拿走了它们。
- 1 回答
- 0 关注
- 331 浏览
添加回答
举报