从微秒创建 Java DateTime Instant
Create Java DateTime Instant from microseconds
自 Java 9 以来,Java 日期和时间 API 发生了变化。
LocalDateTime 现在具有微秒精度。
Java 9 has a fresh implementation of java.time.Clock capable of capturing the current moment in resolution finer than milliseconds (three digits of decimal fraction).
我们从后端服务获取以微秒为单位的时间。
System.currentTimeMillis > 1565245051795 > 2019-08-08T06:17:31.795
Service.getTime > 1565245051795306 > 2019-08-08T06:17:31.795306
为了构建要在我们的应用程序中使用的 LocalDateTime,我们这样做
long timeMicros = service.getTime();
long timeMillis = timeMicros / 1000;
LocalDateTime ldt = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
为了查询服务,我们再次需要时间微秒,然后我们做
long timeMillis = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long timeMicros = timeMillis * 1000;
问题是我们没有得到微秒精度的时间。
是否可以创建微秒精度的 Instant?
我们现在使用 Java 11。当我们的一个 JUnit 测试由于增加的微秒精度而失败时,我注意到了这一变化。
对于 JUnit 测试,我找到了一个解决方法:
private static final LocalDateTime START = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
我不确定这是解决方法还是实际解决方案,但从时间戳中添加最后三个微秒数字似乎可行。
long micros = 306L; //TODO get the last three digits from the timeMicros
ldt.plus(micros, ChronoUnit.MICROS));
long timeMicros = 1_565_245_051_795_306L;
Instant i = Instant.EPOCH.plus(timeMicros, ChronoUnit.MICROS);
System.out.println(i);
输出为:
2019-08-08T06:17:31.795306Z
编辑: 与其用除法和乘法将微秒转换为毫秒 and/or 秒,我更喜欢使用对微秒的内置支持。此外,当明确地将它们添加到时代时,感觉有点手持。
您已经知道如何将 Instant
转换为 LocalDateTime
,您已经在问题中展示了,所以我不再重复。
编辑:
Do you have a solution to get the timeMicros back from the Instant?
有几个选项。这样计算就不那么复杂了,所以我可能会这样做:
long microsBack = TimeUnit.SECONDS.toMicros(i.getEpochSecond())
+ TimeUnit.NANOSECONDS.toMicros(i.getNano());
System.out.println(microsBack);
1565245051795306
为了在第一次转换时更有风格,您可能更喜欢稍微短一点的:
long microsBack = ChronoUnit.MICROS.between(Instant.EPOCH, i);
编辑: 可能是吹毛求疵,但也是为了避免任何人误解:LocalDateTime
一直具有纳秒精度。只有 now
方法在 Java 8 上具有毫秒精度。我在某处读到 Java 9 精度因平台而异,但你是对的,微秒精度似乎很典型。
自 Java 9 以来,Java 日期和时间 API 发生了变化。 LocalDateTime 现在具有微秒精度。
Java 9 has a fresh implementation of java.time.Clock capable of capturing the current moment in resolution finer than milliseconds (three digits of decimal fraction).
我们从后端服务获取以微秒为单位的时间。
System.currentTimeMillis > 1565245051795 > 2019-08-08T06:17:31.795
Service.getTime > 1565245051795306 > 2019-08-08T06:17:31.795306
为了构建要在我们的应用程序中使用的 LocalDateTime,我们这样做
long timeMicros = service.getTime();
long timeMillis = timeMicros / 1000;
LocalDateTime ldt = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
为了查询服务,我们再次需要时间微秒,然后我们做
long timeMillis = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long timeMicros = timeMillis * 1000;
问题是我们没有得到微秒精度的时间。
是否可以创建微秒精度的 Instant?
我们现在使用 Java 11。当我们的一个 JUnit 测试由于增加的微秒精度而失败时,我注意到了这一变化。
对于 JUnit 测试,我找到了一个解决方法:
private static final LocalDateTime START = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
我不确定这是解决方法还是实际解决方案,但从时间戳中添加最后三个微秒数字似乎可行。
long micros = 306L; //TODO get the last three digits from the timeMicros
ldt.plus(micros, ChronoUnit.MICROS));
long timeMicros = 1_565_245_051_795_306L;
Instant i = Instant.EPOCH.plus(timeMicros, ChronoUnit.MICROS);
System.out.println(i);
输出为:
2019-08-08T06:17:31.795306Z
编辑: 与其用除法和乘法将微秒转换为毫秒 and/or 秒,我更喜欢使用对微秒的内置支持。此外,当明确地将它们添加到时代时,感觉有点手持。
您已经知道如何将 Instant
转换为 LocalDateTime
,您已经在问题中展示了,所以我不再重复。
编辑:
Do you have a solution to get the timeMicros back from the Instant?
有几个选项。这样计算就不那么复杂了,所以我可能会这样做:
long microsBack = TimeUnit.SECONDS.toMicros(i.getEpochSecond())
+ TimeUnit.NANOSECONDS.toMicros(i.getNano());
System.out.println(microsBack);
1565245051795306
为了在第一次转换时更有风格,您可能更喜欢稍微短一点的:
long microsBack = ChronoUnit.MICROS.between(Instant.EPOCH, i);
编辑: 可能是吹毛求疵,但也是为了避免任何人误解:LocalDateTime
一直具有纳秒精度。只有 now
方法在 Java 8 上具有毫秒精度。我在某处读到 Java 9 精度因平台而异,但你是对的,微秒精度似乎很典型。