如何将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时间戳字符串转换为纪元?的主要内容,如果未能解决你的问题,请参考以下文章
使用 sql 将字符串纪元代码从 unix 时间戳转换为日期