Home > front end >  Proper way to get EPOCH timestamp in kotlin
Proper way to get EPOCH timestamp in kotlin

Time:12-06

I want to get the EPOCH timestamp in kotlin in "seconds":"nanoseconds" format.

Note: Please look at the accepted answer for the right solution.

Edit:

It's my current solution and I'm sure there would be some better way to achieve this,

import java.time.Instant
import java.time.temporal.ChronoUnit;
import kotlin.time.Duration.Companion.seconds

fun main() {
    val epochNanoseconds = ChronoUnit.NANOS.between(Instant.EPOCH, Instant.now())
    val epochSeconds = epochNanoseconds/1.seconds.inWholeNanoseconds
    val remainingFractionOfNanoSeconds = epochNanoseconds%1.seconds.inWholeNanoseconds
    println("$epochSeconds:$remainingFractionOfNanoSeconds")
}

example output:

1670251213:849754000

Is there any way to get seconds and remaining nanoseconds directly from java.time.Instant or any other library available to achieve this conveniently?

Solution from the accepted answer:

import java.time.Instant

fun main() {
    println("${Instant.now().epochSecond}:${Instant.now().nano}")
}

CodePudding user response:

tl;dr

You are working too hard.

Ask the Instant object for its count of whole seconds since 1970-01-01T00:00Z. Make a string of that, append the COLON character. Then append the count of nanoseconds in the fractional second of the Instant.

instant.getEpochSecond() 
  ":" 
  instant.getNano() 

1670220134:130848

Details

Neither the legacy date-time classes (Calendar, Date, etc.) nor the modern java.time classes support International Atomic Time (TAI). Time-keeping on conventional computers (and therefore Java) is nowhere near as accurate as an atomic clock.

Perhaps you used that term loosely, and really just want a count of nanoseconds since the epoch reference of first moment of 1970 as seen with an offset from UTC of zero hours-minutes-seconds (1970-01-01T00:00Z) within the limits of conventional computer hardware.

If so, the Instant class will work for you. But beware of limitations in the implementations of Java based on the OpenJDK codebase.

  • In Java 8, the first with java.time classes, the current moment is captured with a resolution of milliseconds.
  • In Java 9 , the current moment is captured with a resolution of microseconds (generally, depending on the limits of your computer hardware).

Note that in all versions (8, 9, and later), an Instant is capable of nanosecond resolution. The limitations bulleted above relate to capturing the current moment from the computer hardware clock.

The internal representation of a moment in the Instant class comprises two parts:

  • A count of whole seconds since 1970-01-01T00:00Z.
  • A fractional second represented by a count of nanoseconds.

The Instant class provides a pair of accessor methods (getters) to see both of these numbers.

Your Question is not entirely clear, you seem to be asking for those two numbers with a COLON character between them.

Instant instant = Instant.now() ;
String nanos = Long.toString( instant.getNano() ) ;
String output = 
    instant.getEpochSecond() 
      ":" 
      instant.getNano()
;

instant.toString(): 2022-12-05T06:12:33.294698Z

output: 1670220753:294698

If you want to pad zeros to the right of your fractional second, use String.format.

Instant instant = Instant.now() ;
String nanos = Long.toString( instant.getNano() ) ;
String output = 
    instant.getEpochSecond() 
      ":" 
      String.format( "%1$"   nanos.length()   "s", nanos ).replace(' ', '0') // Pad with leading zeros if needed.
;

See this code run at Ideone.com.

instant.toString(): 2022-12-05T06:12:33.294698Z

output: 1670220753:294698000

Alternatively, you could instantiate a BigDecimal object.

  • Related