我写一个程序,它涉及了很多与时区和对着干。 两件事情我处理大多是从“现在”创建日期时间对象,然后定位一个天真的DateTime对象。
从现在开始在太平洋时区创建DateTime对象,我目前做这个(蟒蛇2.7.2+)
from datetime import datetime
import pytz
la = pytz.timezone("America/Los_Angeles")
now = datetime.now(la)
这是正确的有关于DST? 如果不是这样,我想我应该做的:
now2 = la.localize(datetime.now())
我的问题是为什么呢? 谁能告诉我的情况下,首先是错误的,而秒数是正确的?
至于我秒的问题,假设我有从9/1/2012一些用户输入一个天真的日期和时间上午8:00在洛杉矶,CA. 就是让这样的日期时间的正确方法:
la.localize(datetime(2012, 9, 1, 8, 0))
如果不是这样,我应该如何构建这些日期时间?
从pytz文档 :
处理时间的最佳方式是始终UTC工作,转换才产生的localtime输出时,由人来阅读。
所以,最好你应该使用utcnow
,而不是now
。
假如由于某种原因,你的双手被缚,你需要与本地时间工作,你仍然可以与尝试,如果你夏令转变窗口期间做本地化当前时间遇到了问题。 同样的datetime
可能会出现两次,在白天的时间一次又一次在标准时间和localize
方法不知道如何解决冲突,除非你用告诉它明确is_dst
参数。
因此,要获得当前UTC时间:
utc = pytz.timezone('UTC')
now = utc.localize(datetime.datetime.utcnow())
并把它转换为本地时间(但只有当你必须):
la = pytz.timezone('America/Los_Angeles')
local_time = now.astimezone(la)
编辑:作为被评论中指出@JF塞巴斯蒂安 ,使用您的第一个例子datetime.now(tz)
将适用于所有情况。 正如我上面列出的秋天过渡期间,你的第二个例子失败。 我还是主张使用UTC而不是本地时间,除了显示一切。
第一种方案是关于DST正确的,第二个解决方案是坏的。
我举一个例子。 在这里,在欧洲,这段代码运行时:
from datetime import datetime
import pytz # $ pip install pytz
la = pytz.timezone("America/Los_Angeles")
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
now = datetime.now(la)
now2 = la.localize(datetime.now())
now3 = datetime.now()
print(now.strftime(fmt))
print(now2.strftime(fmt))
print(now3.strftime(fmt))
我得到如下:
2012-08-30 12:34:06 PDT-0700
2012-08-30 21:34:06 PDT-0700
2012-08-30 21:34:06
datetime.now(la)
创建与LA当前时间的日期时间,加上LA时区信息。
la.localize(datetime.now())
增加了时区信息到幼稚日期时间,但不执行时区转换; 它只是假定的时间已经在这个时区。
datetime.now()
创建了一个天真的日期时间(无时区信息)和本地时间。
只要你是在洛杉矶,你会看不出来区别,但如果你的代码运行在其他地方,它可能不会做你想要的。
除此之外,如果你需要与时区认真对待,最好是在UTC你所有的时间,为自己节省了大量的与DST麻烦。
这工作:
# naive datetime
d = datetime.datetime(2016, 11, 5, 16, 43, 45)
utc = pytz.UTC # UTC timezone
pst = pytz.timezone('America/Los_Angeles') # LA timezone
# Convert to UTC timezone aware datetime
d = utc.localize(d)
>>> datetime.datetime(2016, 11, 5, 16, 43, 45, tzinfo=<UTC>)
# show as in LA time zone (not converting here)
d.astimezone(pst)
>>> datetime.datetime(2016, 11, 5, 9, 43, 45,
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)
# we get Pacific Daylight Time: PDT
# add 1 day to UTC date
d = d + datetime.timedelta(days=1)
>>> datetime.datetime(2016, 11, 6, 16, 43, 45, tzinfo=<UTC>)
d.astimezone(pst) # now cast to LA time zone
>>> datetime.datetime(2016, 11, 6, 8, 43, 45,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
# Daylight saving is applied -> we get Pacific Standard Time PST
这不起作用:
# naive datetime
d = datetime.datetime(2016, 11, 5, 16, 43, 45)
utc = pytz.UTC # UTC timezone
pst = pytz.timezone('America/Los_Angeles') # LA timezone
# convert to UTC timezone aware datetime
d = utc.localize(d)
>>> datetime.datetime(2016, 11, 5, 16, 43, 45, tzinfo=<UTC>)
# convert to 'America/Los_Angeles' timezone: DON'T DO THIS
d = d.astimezone(pst)
>>> datetime.datetime(2016, 11, 5, 9, 43, 45,
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)
# we are in Pacific Daylight Time PDT
# add 1 day to LA local date: DON'T DO THAT
d = d + datetime.timedelta(days=1)
>>> datetime.datetime(2016, 11, 6, 9, 43, 45,
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)
# Daylight Saving is NOT respected, we are still in PDT time, not PST
结论:
datetime.timedelta()
不考虑夏令时。
难道你的时间添加/ UTC时区减去ALWAYS。 投射到当地时间仅输出/显示。
该pytz网站说:
不幸的是使用标准的datetime建设者“”不起作用'与pytz许多时区的tzinfo说法。
所以,你不应该使用datetime.now(la)
我不知道具体情况,但有些时区上更奇特的规则,那么我们习惯进行操作,和Python的日期时间代码无法处理它们。 通过使用pytz的代码,它们应该被正确地处理,因为这是pytz的目的。 它也可能有对发生两次由于在夏令跳跃次数的时间问题。
至于第二个问题,这也正是该文档显示,所以你应该不错。