2011-07-25 43 views
4

所以,我们有'欧洲/莫斯科'TZ在我们的设置。 目前这意味着夏令时(这将在未来发生变化,但现在是UTC + 03/04)。Django时区:感觉有点困惑

据我所知,在将日期保存到数据库和提取数据时使用了此TZ。

现在,我必须将日期时间对象序列化为ISO字符串,包括UTC偏移量。这样做的正确方法是什么?

的日期不包含TZ信息(iedstrftime(“%Z”)是空的)

我想我可以将它们转换为UTC与+00连载:00,但我怎么转换如果我不知道具体日期是否为+03(莫斯科冬季)或+04(莫斯科夏季)

回答

5

我该如何将它们转换为UTC,如果我不知道具体日期是+03(莫斯科冬季)或+04(莫斯科夏季)

没有必要为UTC转换,pytz会为你处理这样的事情。

下面是从时区,天真的日期时间转换为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' 
+0

哇,我该如何将它们转换为UTC,这个看起来很棒 – Guard

3

首先运行new_dt = datetime.replace(tzinfo=tz)创建一个新的可识别时区datetime。然后用%z运行您的datetime.strftime()

请注意,您不能再将日期字符串直接转换回到支持时区的日期时间 - datetime.strptime()不支持%z。所以你需要改为创建一个天真的datetimetzinfo,然后像以前一样做datetime.replace(tzinfo=tz)

一些有用的外部库:

http://pytz.sourceforge.net/

http://code.google.com/p/parsedatetime/

http://labix.org/python-dateutil

也可以尝试在这里对堆栈溢出寻找在(Python或Django的OR的AppEngine)AND(日期时间更多的问题或时区或日期或时间或tzinfo)。

+0

通过说'new_dt = datetime.replace(tzinfo = TZ)'你是什么'tz'是什么意思?我知道Django记住了'欧洲/莫斯科'的日期。我怎么能将它转换为UTC /什么?什么应该作为'tz'传递? – Guard

+0

看看它发布的'pytz'链接,它有一串'tzinfo'项目作为'tzinfo'部分可以传递给那个函数。 – agf

+0

我接受@sayap的答案作为更具体的答案,但是我很感谢你的早期提示,并在此提出了赞成。 – Guard

1

ISO-8601没有“时区”的概念,只有日期和时间,为了方便起见,时间可以用“偏移量”来表示。

为了让事情变得更加烦人,datetime只承认时区有点半点点头; datetime对象上的tzinfo属性是可选的,并且主线python没有提供该接口的实现。

对此的标准答案是始终以UTC做所有事情;包括将服务器设置为UTC,而不是在当地时间。这实际上是一个不错的主意;不是时代不同,只有个人用户喜欢阅读这些时间的方式(这与'0'比'0101010'更喜欢''相似)。

您可以通过将首选时区(如果每个人都在莫斯科时只是一个网站范围内的首选项)与实际时间分开来满足用户(合理!)查看其当地时区的时间的愿望,然后您可以使用一个强大的时区库(如pytz)可根据当地时间进行格式设置。

+0

这是完全正确和可以理解的。不幸的是,该网站已经工作了一段时间(我刚刚加入了该团队),并且日期已经存储在由Django设置的欧洲/莫斯科存储的数据库中。那么,我有可能从这些数据中恢复UTC时间吗? – Guard

+1

这是你的问题吗?从原始问题中不清楚您是否尝试将数据库从本地时间迁移到UTC。如果是这样,你应该更新你的问题。 – SingleNegationElimination

+0

我没有迁移数据库。我必须使用正确的偏移量以ISO格式输出数据库中的日期时间。我认为,问题的最后一句清楚地指出:“如果我不知道具体日期是+03(莫斯科冬季)还是+04(莫斯科夏天)” – Guard