天真datetime
与意识datetime
默认datetime
对象被称为“天真”的:它们保留时间信息而没有时区信息。可以将朴素的名字想datetime
成一个+4
没有明确来源的相对数字(即:)(实际上,您的来源在整个系统边界中都是常见的)。
相比之下,请考虑将意识datetime
看作8
是全世界共有的绝对数(即:)。
没有时区信息,您将无法将“原始”日期时间转换为任何非原始时间表示形式(+4
如果我们不知道从哪里开始,目标会在哪里?)。这就是为什么您没有datetime.datetime.toutctimestamp()
方法的原因。(参见:http : //bugs.python.org/issue1457227)
要检查您datetime
dt
是否天真,请检查dt.tzinfo
,如果是None
,则表示天真:
datetime.now()
datetime(1970, 1, 1)
我的约会时间很晚,该怎么办?
您必须根据自己的具体情况做出假设:您必须问自己的问题是:您是否datetime
在UTC上?还是当地时间?
如果您使用的是UTC(没有麻烦):
import calendar
def dt2ts(dt):
"""Converts a datetime object to UTC timestamp
naive datetime will be considered UTC.
"""
return calendar.timegm(dt.utctimetuple())
如果您不使用UTC,欢迎来到地狱。
datetime
在使用前一个功能之前,您必须先将其恢复为原先的时区,以使其天真。
您将需要时区的名称,以及在生成目标原始日期时间时有关DST是否生效的信息(关于DST的最后一个信息对于角落情况是必需的):
import pytz
mytz = pytz.timezone('Europe/Amsterdam')
dt = mytz.normalize(mytz.localize(dt, is_dst=True))
不提供的后果is_dst
:
is_dst
如果在设置了向后DST的同时生成了目标日期时间(例如,通过删除一小时来更改DST时间),则不使用将产生不正确的时间(以及UTC时间戳)。
is_dst
当然,仅提供错误的遗嘱只会在DST重叠或空洞时生成错误的时间(和UTC时间戳)。而且,如果还提供了不正确的时间,则出现在“空洞”中(由于DST向前移动而永远不存在的时间),is_dst
将解释如何考虑该虚假时间,这是唯一在
.normalize(..)
此处实际做些事情的情况,因为它将随后将其转换为实际有效时间(如果需要,请更改datetime和DST对象)。请注意,.normalize()
不需要在末尾具有正确的UTC时间戳,但是如果您不喜欢在变量中使用虚假时间的想法,尤其是在其他地方重用此变量时,建议您这样做。
并避免使用以下内容:(参见:使用pytz进行Datetime时区转换)
dt = dt.replace(tzinfo=timezone('Europe/Amsterdam'))
为什么?因为.replace()
在tzinfo
不考虑目标时间的情况下盲目替换,将选择一个不良的DST对象。而.localize()
使用目标时间和is_dst
提示来选择正确的DST对象。
OLD错误答案(感谢@JFSebastien提出):
希望您可以很容易地在创建朴素datetime
对象时猜测时区(您的本地来源),因为它与系统配置有关,希望您不会在朴素日期时间对象创建和获取日期之间进行更改。 UTC时间戳。这个技巧可以用来提出一个不完善的问题。
通过使用time.mktime
我们可以创建一个utc_mktime
:
def utc_mktime(utc_tuple):
"""Returns number of seconds elapsed since epoch
Note that no timezone are taken into consideration.
utc tuple must be: (year, month, day, hour, minute, second)
"""
if len(utc_tuple) == 6:
utc_tuple += (0, 0, 0)
return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))
def datetime_to_timestamp(dt):
"""Converts a datetime object to UTC timestamp"""
return int(utc_mktime(dt.timetuple()))
您必须确保datetime
在与创建您的对象相同的时区创建对象datetime
。
最后一个解决方案是不正确的,因为它假设从现在开始的UTC偏移量与从EPOCH开始的UTC偏移量相同。对于许多时区(在夏时制(DST)偏移量的一年中的特定时间)而言,情况并非如此。
then.strftime('%s')
期望当地时间,但时间戳指示该时间datetime(2008, 1, 1)
是UTC。