那么,我们在设置中设置了'Europe/Moscow' TZ。目前,这意味着夏令时(这将在未来改变,但目前是UTC+03/04)。
我理解这个TZ是在将日期保存到DB和提取它们时使用的。
现在,我必须将datetime对象序列化为ISO字符串,包括UTC偏移量。正确的做法是什么?
日期不包含TZ信息(即d.s treftime ('%z')为空)
我认为我可以将它们转换为UTC并以+00:00序列化,但如果我不知道特定日期是+03(莫斯科冬季)还是+04(莫斯科夏季),我如何将它们转换为UTC
如果我不知道具体日期是+03(莫斯科冬季)还是+04(莫斯科夏季),如何将它们转换为UTC
不需要UTC转换,pytz会为你处理这些事情。
下面是将无时区datetime转换为具有时区偏移的ISO的代码:
from datetime import datetime
from pytz import timezone
server_timezone = timezone('Europe/Moscow')
server_timezone.localize(datetime(2011, 1, 1)).isoformat()
>>> '2011-01-01T00:00:00+03:00'
server_timezone.localize(datetime(2011, 7, 1)).isoformat()
>>> '2011-07-01T00:00:00+04:00'
首先运行new_dt = datetime.replace(tzinfo=tz)
,创建一个新的支持时区的datetime
。然后运行datetime.strftime()
和%z
。
请注意,您不能直接将日期字符串转换回具有时区意识的日期时间——datetime.strptime()
不支持%z
。因此,您需要创建一个朴素的datetime
和tzinfo
,然后像以前一样执行datetime.replace(tzinfo=tz)
。
也可以尝试在Stack Overflow上搜索更多关于(Python或django或appengine)和(datetime或timezone或date或time或tzinfo)的问题。
ISO-8601没有"时区"的概念,只有日期和时间,为了方便,时间可以用"偏移量"表示。
更让人讨厌的是,datetime
只有一个半心半意的点头来确认时区;datetime对象上的tzinfo属性是可选的,并且主线python不提供该接口的实现。
这个问题的标准答案是总是使用UTC;包括让服务器使用UTC时间,而不是本地时间。这其实是个不错的主意;不是时代不同,只是个人用户更喜欢阅读这些时代的方式不同(这类似于喜欢"42"而不是"0b101010")。
您可以通过将首选时区(如果每个人都在莫斯科,可能只是站点范围内的首选时区)与实际时间分开存储来满足用户(合理的!)查看本地时区时间的愿望,然后您可以使用一个健壮的时区库(如pytz)来进行本地时间和本地时间的格式化。