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.