从微秒创建Java DateTime Instant [英] Create Java DateTime Instant from microseconds
问题描述
Java Date&中发生了变化. Java 9以来的Time API. 现在,LocalDateTime的精度为微秒.
There has been changes in Java Date & Time API Since Java 9. LocalDateTime now has microseconds precision.
Java 9具有java.time.Clock的全新实现,能够以小于毫秒(十进制的三位数)的分辨率捕获当前时刻.
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).
我们从后端服务获得的时间以微秒为单位.
We get the time in microseconds from our backend service.
System.currentTimeMillis > 1565245051795 > 2019-08-08T06:17:31.795
Service.getTime > 1565245051795306 > 2019-08-08T06:17:31.795306
为了构造要在我们的应用程序中使用的LocalDateTime,我们要做
In order to construct a LocalDateTime to be used in our application, we do
long timeMicros = service.getTime();
long timeMillis = timeMicros / 1000;
LocalDateTime ldt = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
要查询服务,我们需要再次花费时间微秒,然后我们要做
For querying the service we need time microseconds again, then we do
long timeMillis = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
long timeMicros = timeMillis * 1000;
问题在于我们无法获得时间微秒级的精度.
The problem is we do not get back the time microseconds precision.
是否可以创建具有微秒级精度的Instant?
我们现在正在使用Java11.由于微秒精度的提高,当我们的一个JUnit测试失败时,我注意到了这一变化.
Is it possible to create an Instant with microsecond precision?
We are now using Java 11. I noticed this change when one of our JUnit tests failed because of the increased microsecond precision.
对于JUnit测试,我找到了一种解决方法:
For the JUnit test I found a workaround:
private static final LocalDateTime START = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
我不确定这是解决方法还是实际的解决方法,但是添加时间戳中的最后三微秒的数字似乎可行.
I'm not sure if this is a workaround or an actual solution, but adding the last three microseconds digits from the timestamp seems to work.
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
2019-08-08T06:17:31.795306Z
我宁愿使用内置的微秒支持,也不愿除以乘以将微秒转换为毫秒和/或秒.同样,当将它们显式添加到纪元时,会感觉有点手持.
Rather than dividing and multiplying to convert microseconds to milliseconds and/or seconds I preferred to use the built-in support for microseconds. Also when explicitly adding them to the epoch feels a little hand-held.
您已经知道如何将Instant
转换为LocalDateTime
,已在问题中对其进行了介绍,所以我不再重复.
You already know how to convert Instant
to LocalDateTime
, you’ve shown it in the question, so I am not repeating that.
您是否有解决方案,可以从即时消息中获取timeMicros?
Do you have a solution to get the timeMicros back from the Instant?
有两种选择.这样,计算就不会那么复杂,所以我可以这样做:
There are a couple of options. This way the calculation is not so complicated, so I might do:
long microsBack = TimeUnit.SECONDS.toMicros(i.getEpochSecond())
+ TimeUnit.NANOSECONDS.toMicros(i.getNano());
System.out.println(microsBack);
1565245051795306
1565245051795306
要在第一次转换时更加时尚,您可能希望使用略短一些的
To be more in style with the first conversion you may prefer the slightly shorter:
long microsBack = ChronoUnit.MICROS.between(Instant.EPOCH, i);
可能挑剔,但也避免任何误解:LocalDateTime
始终具有纳秒级精度.在Java 8上,只有now
方法具有毫秒级的精度.我从Java 9的某个地方了解到,精度随平台的不同而不同,但是您是对的,微秒级的精度似乎很典型.
Possibly nit-picking, but also to avoid anyone misunderstanding: LocalDateTime
has had nanosecond precision always. Only the now
method had millisecond precision on Java 8. I read somewhere that from Java 9 the precision varies with the platform, but you are right, microsecond precision seems typical.
这篇关于从微秒创建Java DateTime Instant的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!