Create Java DateTime Instant from microseconds

心不动则不痛 提交于 2020-06-13 07:23:48

问题


There has been changes in Java Date & Time API Since Java 9. LocalDateTime now has microseconds precision.

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

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.

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.

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));

回答1:


    long timeMicros = 1_565_245_051_795_306L;
    Instant i = Instant.EPOCH.plus(timeMicros, ChronoUnit.MICROS);
    System.out.println(i);

Output is:

2019-08-08T06:17:31.795306Z

Edit: 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.

You already know how to convert Instant to LocalDateTime, you’ve shown it in the question, so I am not repeating that.

Edit:

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

To be more in style with the first conversion you may prefer the slightly shorter:

    long microsBack = ChronoUnit.MICROS.between(Instant.EPOCH, i);

Edit: 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.



来源:https://stackoverflow.com/questions/57411881/create-java-datetime-instant-from-microseconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!