How to convert epoch time with nanoseconds to human-readable?
Question:
I have a timestamp in epoch time with nanoseconds – e.g. 1360287003083988472
nanoseconds since 1970-01-01.
The Python datetime objects and conversion methods only support up to millisecond precision.
Is there an easy way to convert this epoch time into human-readable time?
Answers:
First, convert it to a datetime
object with second precision (floored, not rounded):
>>> from datetime import datetime
>>> dt = datetime.fromtimestamp(1360287003083988472 // 1000000000)
>>> dt
datetime.datetime(2013, 2, 7, 17, 30, 3)
Then to make it human-readable, use the strftime()
method on the object you get back:
>>> s = dt.strftime('%Y-%m-%d %H:%M:%S')
>>> s
'2013-02-07 17:30:03'
Finally, add back in the nanosecond precision:
>>> s += '.' + str(int(1360287003083988472 % 1000000000)).zfill(9)
>>> s
'2013-02-07 17:30:03.083988472'
Actually, Python’s datetime
methods handle microsecond precision, not millisecond:
>>> nanos = 1360287003083988472
>>> secs = nanos / 1e9
>>> dt = datetime.datetime.fromtimestamp(secs)
>>> dt.strftime('%Y-%m-%dT%H:%M:%S.%f')
'2013-02-07T17:30:03.083988'
But if you actually need nanoseconds, that still doesn’t help. Your best bet is to write your own wrapper:
def format_my_nanos(nanos):
dt = datetime.datetime.fromtimestamp(nanos / 1e9)
return '{}{:03.0f}'.format(dt.strftime('%Y-%m-%dT%H:%M:%S.%f'), nanos % 1e3)
This gives me:
'2013-02-07T17:30:03.083988472'
Of course you could have done the same thing even if Python didn’t do sub-second precision at all…
def format_my_nanos(nanos):
dt = datetime.datetime.fromtimestamp(nanos / 1e9)
return '{}.{:09.0f}'.format(dt.strftime('%Y-%m-%dT%H:%M:%S'), nanos % 1e9)
It should be noted that ubiquitous libraries numpy
and pandas
can handle Unix time in nanoseconds without further preparation:
import numpy as np
import pandas as pd
unix_ns = 1360287003083988472
np.datetime64(unix_ns, 'ns') # need to specify unit here
# Out[4]: numpy.datetime64('2013-02-08T01:30:03.083988472')
pd.Timestamp(unix_ns) # pd.Timestamp defaults to ns
# Out[5]: Timestamp('2013-02-08 01:30:03.083988472')
# alternatively (also e.g. for list input):
pd.to_datetime(unix_ns)
# Out[6]: Timestamp('2013-02-08 01:30:03.083988472')
numpy / pandas datetime resembles UTC if you do not set a time zone. In vanilla Python datetime, it’s local time.
I have a timestamp in epoch time with nanoseconds – e.g. 1360287003083988472
nanoseconds since 1970-01-01.
The Python datetime objects and conversion methods only support up to millisecond precision.
Is there an easy way to convert this epoch time into human-readable time?
First, convert it to a datetime
object with second precision (floored, not rounded):
>>> from datetime import datetime
>>> dt = datetime.fromtimestamp(1360287003083988472 // 1000000000)
>>> dt
datetime.datetime(2013, 2, 7, 17, 30, 3)
Then to make it human-readable, use the strftime()
method on the object you get back:
>>> s = dt.strftime('%Y-%m-%d %H:%M:%S')
>>> s
'2013-02-07 17:30:03'
Finally, add back in the nanosecond precision:
>>> s += '.' + str(int(1360287003083988472 % 1000000000)).zfill(9)
>>> s
'2013-02-07 17:30:03.083988472'
Actually, Python’s datetime
methods handle microsecond precision, not millisecond:
>>> nanos = 1360287003083988472
>>> secs = nanos / 1e9
>>> dt = datetime.datetime.fromtimestamp(secs)
>>> dt.strftime('%Y-%m-%dT%H:%M:%S.%f')
'2013-02-07T17:30:03.083988'
But if you actually need nanoseconds, that still doesn’t help. Your best bet is to write your own wrapper:
def format_my_nanos(nanos):
dt = datetime.datetime.fromtimestamp(nanos / 1e9)
return '{}{:03.0f}'.format(dt.strftime('%Y-%m-%dT%H:%M:%S.%f'), nanos % 1e3)
This gives me:
'2013-02-07T17:30:03.083988472'
Of course you could have done the same thing even if Python didn’t do sub-second precision at all…
def format_my_nanos(nanos):
dt = datetime.datetime.fromtimestamp(nanos / 1e9)
return '{}.{:09.0f}'.format(dt.strftime('%Y-%m-%dT%H:%M:%S'), nanos % 1e9)
It should be noted that ubiquitous libraries numpy
and pandas
can handle Unix time in nanoseconds without further preparation:
import numpy as np
import pandas as pd
unix_ns = 1360287003083988472
np.datetime64(unix_ns, 'ns') # need to specify unit here
# Out[4]: numpy.datetime64('2013-02-08T01:30:03.083988472')
pd.Timestamp(unix_ns) # pd.Timestamp defaults to ns
# Out[5]: Timestamp('2013-02-08 01:30:03.083988472')
# alternatively (also e.g. for list input):
pd.to_datetime(unix_ns)
# Out[6]: Timestamp('2013-02-08 01:30:03.083988472')
numpy / pandas datetime resembles UTC if you do not set a time zone. In vanilla Python datetime, it’s local time.