具有纳秒分辨率的 Java 8 Instant.now()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20689055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Instant.now() with nanosecond resolution?
提问by user1615355
Java 8's java.time.Instant stores in "nanosecond resolution", but using Instant.now() only provides millisecond resolution...
Java 8 的 java.time.Instant 以“纳秒分辨率”存储,但使用 Instant.now() 仅提供毫秒分辨率...
Instant instant = Instant.now();
System.out.println(instant);
System.out.println(instant.getNano());
Result...
结果...
2013-12-19T18:22:39.639Z
639000000
How can I get an Instant whose value is 'now', but with nanosecond resolution?
如何获得值为“现在”但具有纳秒分辨率的 Instant ?
回答by Meno Hochschild
You can only get an Instant with "nanoseconds" by using another more precise java.time.Clock by using the Instant-method public static Instant now(Clock clock)
In your example the default clock normally uses System.currentTimeMillis() which cannot display any nanoseconds.
您只能通过使用 Instant-method 使用另一个更精确的 java.time.Clock 来获得具有“纳秒”的 Instantpublic static Instant now(Clock clock)
在您的示例中,默认时钟通常使用 System.currentTimeMillis() ,它无法显示任何纳秒。
Be aware that there is no clock available in nanosecond resolution (real time). The internal nanosecond representation facility of java.time.Instant is mainly due to the requirement to map database timestamps given in nanosecond precision (but normally not accurate to nanoseconds!).
请注意,没有可用纳秒分辨率(实时)的时钟。java.time.Instant 的内部纳秒表示工具主要是由于需要映射以纳秒精度给出的数据库时间戳(但通常不精确到纳秒!)。
Update from 2015-12-29:Java-9 will deliver a better clock, see my newer post.
2015 年12 月 29 日更新:Java-9 将提供更好的时钟,请参阅我的新帖子。
回答by Marko Topolnik
You can consider yourself lucky if you get even millisecond resolution.
如果您获得甚至毫秒的分辨率,您就可以认为自己很幸运。
Instant
may modelthe time to nanosecond precision, but the real-life equipment on your computer which tracks wall-clock time usually has resolution around 10 ms, and accuracy almost certainly quite a bit below that (100 ms would be an optimistic assumption).
Instant
可能会将时间建模为纳秒精度,但是您计算机上跟踪挂钟时间的真实设备通常具有大约 10 毫秒的分辨率,并且精度几乎肯定会低于该值(100 毫秒将是一个乐观的假设)。
Compare this with System.nanoTime()
, which gives resolution in the microseconds, but doesn't give absolute wall-clock time. Clearly, there is already a tradeoff at work to give you that kind of resolution, still three orders of magnitude short of nanoseconds.
将此与 比较System.nanoTime()
,它以微秒为单位提供分辨率,但不提供绝对挂钟时间。显然,已经有一个折衷方案可以为您提供这种分辨率,仍然比纳秒短三个数量级。
回答by StormeHawke
So I spent some time digging through the Javadoc here:
所以我花了一些时间在这里挖掘 Javadoc:
http://download.java.net/jdk8/docs/api/java/time/Instant.html
http://download.java.net/jdk8/docs/api/java/time/Instant.html
It appears that you should be able to do the following:
看来您应该能够执行以下操作:
Instant inst = Instant.now();
long time = inst.getEpochSecond();
time *= 1000000000l; //convert to nanoseconds
time += inst.getNano(); //the nanoseconds returned by inst.getNano() are the nanoseconds past the second so they need to be added to the epoch second
That said - the other answerers make a good point that it's going to be mighty hard to get an accurate nano-second time as computers just don't typically have the capacity to track time to that resolution
也就是说 - 其他回答者提出了一个很好的观点,即获得准确的纳秒时间将非常困难,因为计算机通常没有能力跟踪该分辨率的时间
回答by logtwo
While default Java8 clock does not provide nanoseconds resolution, you can combine it with Java ability to measure time differenceswith nanoseconds resolution, thus creating an actual nanosecond-capable clock.
虽然默认的 Java8 时钟不提供纳秒分辨率,但您可以将它与 Java 功能结合起来以纳秒分辨率测量时间差异,从而创建一个实际的纳秒时钟。
public class NanoClock extends Clock
{
private final Clock clock;
private final long initialNanos;
private final Instant initialInstant;
public NanoClock()
{
this(Clock.systemUTC());
}
public NanoClock(final Clock clock)
{
this.clock = clock;
initialInstant = clock.instant();
initialNanos = getSystemNanos();
}
@Override
public ZoneId getZone()
{
return clock.getZone();
}
@Override
public Instant instant()
{
return initialInstant.plusNanos(getSystemNanos() - initialNanos);
}
@Override
public Clock withZone(final ZoneId zone)
{
return new NanoClock(clock.withZone(zone));
}
private long getSystemNanos()
{
return System.nanoTime();
}
}
Using it is straightforward: just provide extra parameter to Instant.now(), or call Clock.instant() directly:
使用它很简单:只需为 Instant.now() 提供额外的参数,或者直接调用 Clock.instant():
final Clock clock = new NanoClock();
final Instant instant = Instant.now(clock);
System.out.println(instant);
System.out.println(instant.getNano());
Although this solution might work even if you re-create NanoClock instances every time, it's always better to stick with a stored clock initialized early in your code, then used wherever it's needed.
尽管即使您每次都重新创建 NanoClock 实例,此解决方案也可能有效,但最好坚持使用在代码早期初始化的存储时钟,然后在需要的地方使用。