如何将.NET DateTime.toBinary()转换为java日期



我有一个来自JSON响应的.NET INT64值(DateTime.toBinary((的结果(,为-8586018589234115。如何将该值转换为有效的java日期?

谢谢,Sandeep

二进制值为:

一个64位带符号整数,它将Kind属性编码在2位字段中,将Ticks属性编码在62位字段中。

由于Kind属性对我们来说是无用的,我们可以简单地使用value & ((1L << 62) - 1)来屏蔽它以获得Ticks属性。

勾号是:

一个刻度表示一百纳秒或一千万分之一秒。一毫秒内有10,000个刻度(请参见TicksPerMillisecond(,一秒钟内有1000万个刻度。

此属性的值表示自12:00:00 midnight, January 1, 0001以来经过的100纳秒间隔数。

这意味着我们可以这样转换:

private static final long NANOS_PER_TICK = 100L;
private static final long TICKS_PER_SECOND = 1000000000L / NANOS_PER_TICK;
private static final long YEAR_OFFSET = -62135596800L;
// Seconds from Epoch to 12:00:00 midnight, January 1, 0001, calculated using:
//   OffsetDateTime.of(1, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toEpochSecond()
static Instant fromDateTimeBinary(long value) {
long ticks = value & ((1L << 62) - 1);
return Instant.ofEpochSecond(ticks / TICKS_PER_SECOND + YEAR_OFFSET,
ticks % TICKS_PER_SECOND * NANOS_PER_TICK);
}

测试

long dateTimeBinary = -8586018589234214115L;
System.out.println(dateTimeBinary + " -> " + fromDateTimeBinary(dateTimeBinary));

输出

-8586018589234214115 -> 2020-09-10T14:26:02.056169300Z

警告:-8586018589234214115值指定2=LocalKind值(表示的时间为本地时间(,但我们不知道;本地";时区为,因此转换为UTC的结果可能是错误的。


我们也可以用另一种方式转换:

static long toDateTimeBinary(Instant dateTime) {
long ticks = (dateTime.getEpochSecond() - YEAR_OFFSET) * TICKS_PER_SECOND
+ dateTime.getNano() / NANOS_PER_TICK;
return (0x01L/*Kind=UTC*/ << 62) | ticks;
}

测试

Instant now = Instant.now();
System.out.println(now + " -> " + toDateTimeBinary(now));

输出

2020-12-16T01:51:17.066065200Z -> 5249122821198048556

另请参阅:Java 8时间-等效于.NET DateTime.MaxValue.Ticks

  1. 使用DateTime.FromBinary(Int64)将值(例如,-8586018589234214115(转换为DateTime对象(例如theDateTimeObject(
  2. theDateTimeObject转换为DateTimeOffset作为DateTimeOffset dateTime = DateTime.SpecifyKind(theDateTimeObject, DateTimeKind.Utc)
  3. 传递DateTimeOffset.ToUnixTimeMilliseconds的值转换为java.time.Instant#ofEpochMilli以获得Instant的对象,您可以将其转换为其他日期-时间类型

演示:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
long millis = 1608075095347L;
Instant instant = Instant.ofEpochMilli(millis);
System.out.println(instant);
// You can derive other date-time objects from Instant e.g.
OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(odt);
System.out.println(zdt);
System.out.println(ldt);
}
}

输出:

2020-12-15T23:31:35.347Z
2020-12-15T23:31:35.347Z
2020-12-15T23:31:35.347Z
2020-12-15T23:31:35.347

请注意,java.util的日期时间API及其格式API、SimpleDateFormat已过时且为错误产品。建议完全停止使用它们,并切换到现代日期时间API。有关现代日期时间API的更多信息,请访问跟踪:日期时间

注意:无论出于何种原因,如果您必须坚持使用Java 6或Java 7,您可以使用ThreeTen BackportJava.time的大部分功能向后移植到Java 6&7.

如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查通过desugaring和如何在Android项目中使用ThreeTenABP提供的Java 8+API。

最好转换为unix time.net DateTimeOffset.ToUnixTimeMilliseconds,然后使用java.util.Date java构造函数解析它

最新更新