使用 strftime 将 python 日期时间转换为纪元
Posted
技术标签:
【中文标题】使用 strftime 将 python 日期时间转换为纪元【英文标题】:Convert python datetime to epoch with strftime 【发布时间】:2012-07-29 09:23:25 【问题描述】:我有一个 UTC 时间,我想要从纪元开始的秒数。
我正在使用 strftime 将其转换为秒数。以 2012 年 4 月 1 日为例。
>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'
2012 年 4 月 1 日 UTC 从纪元开始是 1333238400,但以上返回 1333234800,相差 1 小时。
所以看起来 strftime 正在考虑我的系统时间并在某处应用时区转换。我认为 datetime 纯粹是幼稚的吗?
我怎样才能解决这个问题?如果可能避免导入其他库,除非是标准的。 (我有便携性问题)。
【问题讨论】:
相关:Converting datetime.date to UTC timestamp in Python 我是唯一一个注意到您在数字中使用八进制文字的人吗? 相关Python issue: datetime.strftime('%s') should respect tzinfo 较新的 Python 3.3+ 有datetime.datetime.timestamp(datetime.datetime.utcnow())
相反的操作去这里:in-python-how-do-you-convert-seconds-since-epoch-to-a-datetime-object
【参考方案1】:
如果您想将 python 日期时间转换为自纪元以来的秒数,您可以明确地执行此操作:
>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0
在 Python 3.3+ 中,您可以改用 timestamp()
:
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
为什么你不应该使用datetime.strftime('%s')
Python 实际上并不支持 %s 作为 strftime 的参数(如果您检查 http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior 它不在列表中),它工作的唯一原因是因为 Python 正在将信息传递给系统的 strftime,它使用您当地的时区。
>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'
【讨论】:
我一直在疯狂地试图弄清楚为什么我经常看到 strftime("%s") ,但它不在文档中。谢谢你! 不要使用.strftime("%s")
:它不被支持,它不可移植,它可能会默默地为有意识的日期时间对象产生错误的结果,如果输入是UTC,它会失败(如在问题)但本地时区不是 UTC
@earthmeLon 你的包围是错误的。 Timedeltas(通过减去两个日期时间得出)有 total_seconds,但日期时间没有。
这对我不起作用:AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'
@Michael 该功能是 Python 2.7 中的新功能,您必须使用旧版本。对于 2.7 之前的版本,您可以使用 td.seconds + td.days*24*3600
。这会丢弃微秒部分。【参考方案2】:
我在时区等方面存在严重问题。 Python 处理所有这些的方式碰巧很令人困惑(对我来说)。使用日历模块似乎一切正常(请参阅链接 1、2、3 和 4)。
>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400
【讨论】:
+1,因为它是唯一适用于问题输入的答案。 这个便携吗? 这应该被标记为正确答案,因为这回答了相关问题。赞一个 这个“有效”,但请注意问题:“我有一个 UTC 时间”此方法将始终使用系统的本地时区。无法指定时区。如果此示例中的aprilFirst
是“感知”实例并使用与系统时区不同的时区,则结果将不正确(时区在timetuple()
调用中丢失)。要获得“感知”日期时间的正确答案,您可以在最近的 Python 3 上使用awaredt.timestamp()
。对于 Python 2,这更难;一种方法是使用arrow
库。 arrow.get(awaredt).timestamp
会做对的。
好点,@AdamWilliamson,但示例中的代码没有本地化 datetime
对象,所以我假设 "I have a time in UTC" 的意思是OP 有一个不知道的 datetime
对象,假定在 UTC 中,他想为此获得一个 epoch
(如果 datetime
恰好是 TZ 感知的,这可能,确实,改变事物)。另外,请记住,这个答案已经有将近 8 年的历史了,自那以后发生了很多事情(例如,arrow
于 2013 年发布)【参考方案3】:
import time
from datetime import datetime
now = datetime.now()
time.mktime(now.timetuple())
【讨论】:
写time.time()
的方式不正确(mktime()
可能在夏令时转换期间失败,而time.time()
继续工作)。除非当地时区是 UTC(问题中的输入是 UTC),否则它不会回答问题。即使输入代表本地时间,如果 mktime()
不使用 tz 数据库并且本地时区多年来可能具有不同的 UTC 偏移量,例如,2010 年的欧洲/莫斯科,mktime()
也可能在过去/未来日期失败-2015 -- 改用 UTC 时间(如问题所示)或时区感知日期时间对象。
这里是more issues with converting a local time (such as returned by .now()
) to epoch timestamp (returned by mktime()
)。如果你读过它;您了解为什么 UTC 输入(在问题中使用)比表示本地时间的幼稚 datetime 对象更可取【参考方案4】:
import time
from datetime import datetime
now = datetime.now()
# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6
(对不起,它不会让我对现有答案发表评论)
【讨论】:
那是因为time.mktime没有考虑到微秒部分吧? 正确。时间元组结构(基于 C strut)没有微秒空间,所以我们需要从 datetime 对象中获取信息并将其添加到末尾。 it doesn't answer the question unless the local timezone is UTC 在我的机器上,即使我的时区是 ET,它也能正常工作。 这将根据系统的本地时间在不同系统上为您提供不同的时间戳。【参考方案5】:如果你只需要一个 unix /epoch 时间的时间戳,这一行就可以了:
created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L
并且仅依赖于datetime
在 python2 和 python3 中工作
【讨论】:
【参考方案6】:对于明确的独立于时区的解决方案,请使用 pytz 库。
import datetime
import pytz
pytz.utc.localize(datetime.datetime(2012,4,1,0,0), is_dst=False).timestamp()
输出(浮点数):1333238400.0
【讨论】:
在***.com/a/21145908/4355695 看到了一个类似的答案,但是这个作为单线的答案非常适合我的用例,其中传入的数据是 UTC 并且只是 .timestamp() 假设它在当地时间。 这确实适用于小于 1970 的日期。谢谢。接受的答案不适用于小于 1970 年的日期。(Python 3.7.3 64 位 Anaconda3)【参考方案7】:这适用于 Python 2 和 3:
>>> import time
>>> import calendar
>>> calendar.timegm(time.gmtime())
1504917998
按照官方文档... https://docs.python.org/2/library/time.html#module-time
【讨论】:
1) 这假设您现在要转换,而不是随机的日期时间对象。 2)你不需要日历。 time.mktime(randomDateTime.timetuple()) + randomDateTime.microsecond * 1e-6 @CharlesPlager time.mktime 不正确;它在本地时区解释参数,而 OP 希望以 UTC 解释时间(就像 calendar.timegm 一样)。 这是对我来说最准确的答案,如果您希望在 GMT 中转换您的时间并且您希望在转换为纪元时间戳时保持这种方式。 按照你的回答,calendar.timegm(datetime.strptime("2019-05-03T05:40:09.770494+00:00"[:16], '%Y-%m-%dT %H:%M').timetuple()) 我在 utc 中有时间戳,无论你在什么系统上运行它都会给我正确的时间戳,诀窍是使用 strptime.timetumple【参考方案8】:在 Python 3.7 中
以其中一种格式返回与 date_string 对应的日期时间 由 date.isoformat() 和 datetime.isoformat() 发出。具体来说, 此函数支持格式中的字符串 YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]],其中 * 可以匹配任何单个字符。
https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
【讨论】:
请注意,这是在 Python 3.7 中引入的。以上是关于使用 strftime 将 python 日期时间转换为纪元的主要内容,如果未能解决你的问题,请参考以下文章
python时间处理,datetime中的strftime/strptime
(python基础)时间辍time时间元组localtime时间格式化strftime
pandas使用strftime函数将dataframe的日期格式数据列按照指定格式(format)转化为日期(时间)字符串数据列