Convert Instant to microseconds from Epoch time

2019-04-24 09:27发布

问题:

In Instant there are methods:

  • toEpochMilli which converts this instant to the number of milliseconds from the epoch of 1970-01-01T00:00:00Z
  • getEpochSecond which gets the number of seconds from the Java epoch of 1970-01-01T00:00:00Z.

Both of these methods lose precision, e.g. in toEpochMilli JavaDoc I see:

If this instant has greater than millisecond precision, then the conversion drop any excess precision information as though the amount in nanoseconds was subject to integer division by one million.

I don't see corresponding methods to obtain more precise timestamp. How can I get number of micros or nanos from epoch in Java 8?

回答1:

As part of java.time, there are units under java.time.temporal.ChronoUnit that are useful for getting the difference between two points in time as a number in nearly any unit you please. e.g.

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

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

gives the microseconds since epoch for that Instant as a long.



回答2:

Use getNano() together with getEpochSeconds().

int getNano()

Gets the number of nanoseconds, later along the time-line, from the start of the second. The nanosecond-of-second value measures the total number of nanoseconds from the second returned by getEpochSecond.

Convert to desired unit with TimeUnit, as the comment suggested:

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

You can also find out when they overflow:

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