如何将带有纳秒的时期时间转换为可读格式?

34

我有一个时间戳,它是以纪元时间加上纳秒数的形式表示 - 例如:1360287003083988472 自1970年01月01日以来的纳秒数。

Python的datetime对象和转换方法只支持毫秒级精度。

是否有一种简单的方法将这个纪元时间转换成可读的人类时间?


2
@abarnert 我不这么认为。 这个问题涉及将数字转换为可读的字符串,而那一个正在尝试将字符串转换为 datetime 对象。 - ethguo
@ethg242:那个问题有点混乱,但归根结底是一样的:datetime不处理纳秒,所以你必须自己进行数学/字符串操作。也许关于strptimestrftime各有一个问题是可以的。 - abarnert
1
这个比重复的好转了。 - n611x007
1
@abarnert,你有没有看过其他问题的答案?哈哈。不知道为什么,naxa是对的,这个问题的答案结果更好,原因不明。 - victorhooi
@victorhooi:是的,有时候重复问题的答案比原来的更好。这意味着你不应该忽略一个问题,只因为它可能是一个重复问题(请注意这里的两个答案中有一个是我的),但这并不意味着我们不应该标记重复问题。 - abarnert
Python 的 datetime.datetime() 支持微秒级别的精度,而不是毫秒级别的精度。 - Anthon
3个回答

48

首先,将其转换为带有秒精度的 datetime 对象(舍去小数部分,不要四舍五入):

>>> from datetime import datetime
>>> dt = datetime.fromtimestamp(1360287003083988472 // 1000000000)
>>> dt
datetime.datetime(2013, 2, 7, 17, 30, 3)

然后,为了使其易读,可以在获取的对象上使用strftime()方法:

>>> s = dt.strftime('%Y-%m-%d %H:%M:%S')
>>> s
'2013-02-07 17:30:03'

最后,加入纳秒级精度:

>>> s += '.' + str(int(1360287003083988472 % 1000000000)).zfill(9)
>>> s
'2013-02-07 17:30:03.083988472'

1
我在这里的问题是,使用 1360287003083988472 // 1000000000,您有可能会丢失宝贵的信息。相反,可以使用 datetime.fromtimestamp(1360287003083988472 / 1000000000) 来获得人类可读格式。 - r02
@r02. 将uint64转换为float也可能会丢失很多有价值的信息。一个具有64位精度,而另一个实际上只有53位。 - Mad Physicist

17

实际上,Python的datetime方法处理微秒精度,而不是毫秒

>>> 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'

但是,如果你真的需要纳秒级别的精度,那也没有什么用。最好的方法是编写自己的封装:

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)

这给了我:

'2013-02-07T17:30:03.083988472'

当然,即使 Python 没有实现亚秒精度,您仍然可以执行相同的操作...

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)

Unix纪元时间是UTC,因此datetime.utcfromtimestamp(secs)将获取正确的时区,而fromtimestamp将使用系统时区。https://dev59.com/XLXna4cB1Zd3GeqPSuyV#72225603 - Lucas Walter

4
应注意常见的库numpypandas可以在不需要进一步准备的情况下处理纳秒级Unix时间:
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日期时间类似于UTC。在原始的Python datetime中,它是本地时间


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接