User:Daniel Gregoire/Unix Epoch and J Epoch
Today I was processing timestamps that were encoded as milliseconds since the Unix epoch, i.e., 1970-01-01. These were timestamps taken from java.util.Date
objects using the getTime
method.
I read the following on Vocabulary/Foreigns#m6:
Codes 14-17 convert between three representations of times: ISO 8601 timestamp, a list of bytes; nanosecond time, where the time is represented as a signed integer giving the offset in nanoseconds from the epoch, which is midnight on 2000/01/01; and digit time, where the time is represented as an integer whose digits are YYYYMMDDhhmmss. A time argument can be a single time or an array of times. The functions require 64-bit integers.
And I saw multiple mentions of nanoseconds in the rows of the table for codes 14–17, so I multiplied my timestamps by 1e6
but found myself confused until I read the above more closely.
J's foreigns expect nanoseconds since 2000-01-01, not 1970.
J Code
So I wrote these simple definitions to transform my Unix timestamps into J-compatible ones, and then gave a more memorable name to the foreign I wanted to use for debugging individual timestamp values:
NB. Shorten these names as you see fit.
millisToNanos=.*&1e6
millisBetween1970and2000=.946684799999
unixToJ=.millisToNanos@:(-&millisBetween1970and2000)
toIsoDt=.(6!:16)
unixToJ 1546355653000 NB. 599670853001000000
toIsoDt unixToJ 1546355653000 NB. 2019-01-01T15:14:13
With ISO-8601 date/times, I prefer having a timezone identifier on the end. As explained by User:Henry Rich in the forums, the date/time facilities only support appending a the timezone identifier Z, so we can provide that option as the left argument, or we can simply append it ourselves:
NB. Providing x to (6!:16)
'.Z0' toIsoDt unixToJ 1546355653000 NB. 2019-01-01T15:14:13Z
NB. Or just slapping a Z on the end:
'Z',~toIsoDt unixToJ 1546355653000 NB. 2019-01-01T15:14:13Z