Arati Nagmal
Arati Nagmal

Reputation: 60

How to get nanoseconds since epoch for string formatted time "2019-01-25 14:34:34.123456789" in java?

I am able to parse 2019-01-25 14:34:34.123456789 string and get the object of ZonedDateTime. Now, I want to get time in nanoseconds precision level since epoch from this ZonedDateTime object.

Upvotes: 0

Views: 186

Answers (2)

Slawomir Chodnicki
Slawomir Chodnicki

Reputation: 1545

Duration might help:

Something like:

Duration.between(
  ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("UTC")),
  yourZonedDatetime
).toNanos()

Upvotes: 1

Anonymous
Anonymous

Reputation: 86296

This will work until year 2262:

    ZonedDateTime zdt = LocalDateTime.of(2019, 1, 25, 14, 34, 34, 123456789)
            .atZone(ZoneId.of("Asia/Kolkata"));
    Instant i = zdt.toInstant();
    long epochNano = Math.addExact(Math.multiplyExact(i.getEpochSecond(), TimeUnit.SECONDS.toNanos(1)),
            i.getNano());
    System.out.println(NumberFormat.getNumberInstance(Locale.ENGLISH).format(epochNano));

Output:

1,548,407,074,123,456,789

Why I am not just using TimeUnit.SECONDS.toNanos(i.getEpochSecond()) is in case of overflow this would just give me Long.MAX_VALUE, that is, an incorrect result. Math.multiplyExact will throw an exception in case of overflow, so we will discover, which I clearly prefer.

To avoid overflow in year 2262 and later use BigInteger:

    BigInteger epochNano = BigInteger.valueOf(i.getEpochSecond())
            .multiply(BigInteger.valueOf(TimeUnit.SECONDS.toNanos(1)))
            .add(BigInteger.valueOf(i.getNano()));

The result is the same.

Pros and cons: There’s a little more handwork in my code than in the code by Slawomir Chodnicki, which is certainly a disadvantage. On the other hand I didn’t find the use of Duration very well motivated here either, and that will not work after year 2262 either (throws an ArithmeticException). The perfect solution doesn’t exist.

Upvotes: 0

Related Questions