23

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?

Michal Kordas
  • 10,475
  • 7
  • 58
  • 103

3 Answers3

30

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)))
xiaofeng.li
  • 8,237
  • 2
  • 23
  • 30
  • 2
    Good answer. In addition to `getNano()` I suggest you use `TimeUnit` for the conversions involved, and you decide whether you need overflow detection. On one hand the microseconds of `Instant.MIN` and `Instant.MAX` will not fit into a `long`, on the other hand a `long` will suffice for `Instant`s pretty far in the past or the future. – Ole V.V. Dec 18 '17 at 14:09
25

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.

pdxleif
  • 1,750
  • 16
  • 15
1

Try Google Guava: Instants.toEpochMicros(instant)

jeffery.yuan
  • 1,177
  • 1
  • 17
  • 27