将从纪元时间开始的即时时间转换为微秒

24

Instant 中有以下方法:

  • toEpochMilli:将该实例转换为距离1970-01-01T00:00:00Z时刻的毫秒数
  • getEpochSecond:获取Java时代(1970-01-01T00:00:00Z)起的秒数。

这两个方法均会丢失精度,例如在 toEpochMilli 的 JavaDoc 中,我们可以看到:

如果此实例具有高于毫秒级别的精度,则将其转换将删除所有多余的精度信息,就好像以纳秒为单位的数量正在被一百万整除。

我没有看到相应的方法来获取更精确的时间戳。 如何在Java 8中获取自纪元以来的微秒或纳秒数?


对于微控制器,有一个开放请求在 https://bugs.openjdk.java.net/browse/JDK-8196003。 - mkobit
3个回答

30

使用getNano()getEpochSeconds()方法一起使用。

int getNano()

从秒的开始获取沿时间线后面的纳秒数。 秒的纳秒值测量自getEpochSecond返回的秒开始的总纳秒数。

根据注释建议,使用TimeUnit将其转换为所需的单位:

Instant inst = Instant.now();
// Nano seconds since epoch, may overflow
long nanos = TimeUnit.SECONDS.toNanos(inst.getEpochSecond()) + inst.getNano();
// Microseconds since epoch, may overflow
long micros = TimeUnit.SECONDS.toMicros(inst.getEpochSecond()) + TimeUnit.NANOSECONDS.toMicros(inst.getNano());

您还可以查找它们何时溢出:

// 2262-04-11T23:47:16.854775807Z
Instant.ofEpochSecond(TimeUnit.NANOSECONDS.toSeconds(Long.MAX_VALUE), 
                      Long.MAX_VALUE % TimeUnit.SECONDS.toNanos(1));
// +294247-01-10T04:00:54.775807Z
Instant.ofEpochSecond(TimeUnit.MICROSECONDS.toSeconds(Long.MAX_VALUE), 
                      TimeUnit.MICROSECONDS.toNanos(Long.MAX_VALUE % TimeUnit.SECONDS.toMicros(1)))

2
好的回答。除了使用 getNano(),我建议您使用 TimeUnit 进行涉及的转换,并决定是否需要溢出检测。一方面,Instant.MINInstant.MAX 的微秒数不适合放入 long 中,另一方面,对于过去或未来相当远的 Instantlong 将足够。 - Ole V.V.

25

作为java.time的一部分,有一些位于java.time.temporal.ChronoUnit下的单位可以用于以几乎任何单位获取两个时间点之间的差异。

import java.time.Instant;
import java.time.temporal.ChronoUnit;

ChronoUnit.MICROS.between(Instant.EPOCH, Instant.now())

以长整型的形式给出该时刻距离纪元的微秒数。


2
尝试使用Google Guava:Instants.toEpochMicros(instant)

没有叫做 Instants 的 Guava 类... - Ricket

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接