如何将python时间戳字符串转换为纪元?

Posted

技术标签:

【中文标题】如何将python时间戳字符串转换为纪元?【英文标题】:How to convert python timestamp string to epoch? 【发布时间】:2015-08-08 16:58:20 【问题描述】:

我有以下字符串:

mytime = "2009-03-08T00:27:31.807Z"

如何在python中将其转换为纪元?

我试过了:

import time
p = '%Y-%m-%dT%H:%M:%S'
int(time.mktime(time.strptime(s, p)))

但它不适用于31.807Z

【问题讨论】:

你是如何使用 %S 得到类似.807Z 的? %S 显示为十进制数 【参考方案1】:

分为两部分:

    将时间字符串转换为细分时间。见How to parse ISO formatted date in python? Convert the UTC time to "seconds since the Epoch" (POSIX timestamp).
#!/usr/bin/env python
from datetime import datetime

utc_time = datetime.strptime("2009-03-08T00:27:31.807Z", "%Y-%m-%dT%H:%M:%S.%fZ")
epoch_time = (utc_time - datetime(1970, 1, 1)).total_seconds()
# -> 1236472051.807

如果您确定要忽略几分之一秒并获得整数结果:

#!/usr/bin/env python
import time
from calendar import timegm

utc_time = time.strptime("2009-03-08T00:27:31.807Z", "%Y-%m-%dT%H:%M:%S.%fZ")
epoch_time = timegm(utc_time)
# -> 1236472051

要支持与闰秒相对应的时间戳,例如Wed July 1 2:59:60 MSK 2015,您可以use a combination of time.strptime() and datetime (if you care about leap seconds you should take into account the microseconds too)。

【讨论】:

如果您得到“2009-03-08T00:27:31.807A”或祖鲁时间的任何偏移量怎么办?但是 +1 用于区域设置时间转换:) @JoranBeasley 在实践中,除非您有一些特殊要求,否则 rfc 3339 可以工作。 Z 是唯一允许的字母 tools.ietf.org/html/rfc3339#section-5.6【参考方案2】:

您的格式字符串中缺少.%fZ

p = '%Y-%m-%dT%H:%M:%S.%fZ'

转换为epoch的正确方法是使用datetime:

from datetime import datetime

p = '%Y-%m-%dT%H:%M:%S.%fZ'
mytime = "2009-03-08T00:27:31.807Z"
epoch = datetime(1970, 1, 1)
print((datetime.strptime(mytime, p) - epoch).total_seconds())

如果你想忽略分数,也可以调用 int。

【讨论】:

@JoranBeasley。在我无限的智慧中,我预测它总是以Z 结尾,我想你总是可以忽略Z 和 rstrip("Z") 不要在UTC时间使用time.mktime() 这里是可能的终端字符en.wikipedia.org/wiki/List_of_military_time_zones .... 它通常是 Z 对于大多数事情,但那个字母的含义是这个丢弃:/仍然是粗略的可靠答案:) @J.F.Sebastian,是的,当你对 joran 的回答发表评论时,我阅读了这篇文章。 我投了反对票并留下了关于 mktime() 的评论。 “OP 在问题中使用了损坏的代码”并不是将其放入您的答案的有效借口。就个人而言,如果我必须包含损坏的代码,我会在代码片段的顶部添加类似 #XXX WRONG, DON'T USE 的内容。将有效答案放在底部的某处是不够的。【参考方案3】:

dateutil 是我发现的唯一能正确处理时区偏移标识符 (Z) 的库

pip install python-dateutil

然后

from dateutil.parser import parse as date_parse
print date_parse("2009-03-08T00:27:31.807Z")
#get timestamp

import calendar
dt =  date_parse("2009-03-08T00:27:31.807Z")
timestamp1 = calendar.timegm(dt.timetuple())

【讨论】:

可能是更强大的解决方案。 @PadraicCunningham:如果你想拒绝使用错误格式的时间戳,它的健壮性会降低。 dateutil 可能接受太多。 为此使用dateutil 有点过头了。您可以在 Python 2 和 3 中仅使用 stdlib 解析时间字符串。timegm() 可以,如果您不关心几分之一秒。 如果您不想丢失终端信en.wikipedia.org/wiki/List_of_military_time_zones所传递的信息,请不要这样做 @JoranBeasley:唯一允许的字母是 Z。阅读RFC 3339。【参考方案4】:

dateutil 最近被重新添加到 python 包中,它是一个可以自己处理格式的简单的衬垫。

from dateutil import parser
strtime = '2009-03-08T00:27:31.807Z'
epoch = parser.parse(strtime).timestamp()

【讨论】:

只有没有上下文和额外文本的答案不是最好的。您基本上是在要求 OP 在不知道代码功能的情况下复制并粘贴您的答案。请提供解释。谢谢!【参考方案5】:

代码:

import datetime
epoch = datetime.datetime(1970, 1, 1)

mytime = "2009-03-08T00:27:31.807Z"
myformat = "%Y-%m-%dT%H:%M:%S.%fZ"
mydt = datetime.datetime.strptime(mytime, myformat)
val = (mydt - epoch).total_seconds()

print(val)
> 1236472051.81
repr(val)
> '1236472051.807'

注意事项:

使用time.strptime()时,返回的time.struct_time不支持亚秒级精度。 %f format 用于微秒。解析时不必是完整的 6 位数字。

【讨论】:

【参考方案6】:

Python 3.7+ 有问题的字符串格式可以被strptime解析:

from datetime import datetime
datetime.strptime("2009-03-08T00:27:31.807Z", '%Y-%m-%dT%H:%M:%S.%f%z')
>>> datetime.datetime(2009, 3, 8, 0, 27, 31, 807000, tzinfo=datetime.timezone.utc)

使用内置datetime.fromisoformat() 的另一个选项:正如@jfs 链接的this 线程中所述,fromisoformat() 不会将“Z”字符解析为 UTC,尽管这是RFC3339 定义的一部分.一些变通方法可以让它工作 - 有些人会认为这很讨厌,但毕竟是efficient。

from datetime import datetime
mytime = "2009-03-08T00:27:31.807Z"
datetime.fromisoformat(mytime.replace("Z", "+00:00")).timestamp()
>>> 1236472051.807

【讨论】:

相关:***.com/a/62769371/10197418【参考方案7】:

此代码在 Python 3.6 中工作,用于将日期时间字符串转换为 UTC 或本地时区中的纪元。

from datetime import datetime, timedelta
from dateutil.tz import tzutc, tzlocal

mydate = '2020-09-25'
mytime = '06:00:00'

epoch1970 = datetime(1970, 1, 1, 0, 0, 0, tzinfo=tzutc())

myepochutc = int((datetime.strptime(mydate + ' ' + mytime, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzutc()) - epoch1970).total_seconds()*1000)

myepochlocal = int((datetime.strptime(mydate + ' ' + mytime, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzlocal()) - epoch1970).total_seconds()*1000)

#epoch will be in milliseconds
print(myepochutc)   #if mydate/mytime was in utc
print(myepochlocal) #if mydate/mytime was in local timezone

【讨论】:

以上是关于如何将python时间戳字符串转换为纪元?的主要内容,如果未能解决你的问题,请参考以下文章

将小时和分钟字符串转换为纪元(unix 时间戳)

使用 sql 将字符串纪元代码从 unix 时间戳转换为日期

转换为纪元时间戳添加小时偏移量

在Java中将ISO 8601时间戳字符串转换为纪元秒[重复]

将长的 Unix 纪元时间戳转换为实际日期/时间

Unix 纪元时间戳在 Python 中转换为 UTC 时区