查看文章 |
关于pytz的一些记录(续)
2009-02-22 11:20
在昨天与了关于pytz的东西后,还是发现一些问题。 >>> import pytz, datetime >>> tz = pytz.timezone('Asia/Shanghai') >>> tz <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD> 可以看到,它有一个LMT,这是Local Mean Time的缩写,网上查一查意思是本地平均时。而且时间是+8:06,说明与UTC的时差不是8个小时整。先不管它,让我们转换一下试试。 >>> d = datetime.datetime(2009,2,21,23,18,5,tzinfo=tz) >>> d datetime.datetime(2009, 2, 21, 23, 18, 5, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>) 好,时区与tz是一样的,没什么。 >>> x = d.astimezone(pytz.utc) >>> x datetime.datetime(2009, 2, 21, 15, 12, 5, tzinfo=<UTC>) 我们转为了UTC时区,时间上有差异,没问题。 让我们再转回来。 >>> x.astimezone(tz) datetime.datetime(2009, 2, 21, 23, 12, 5, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) 奇怪,看到了吧,变成了CST了。时差也成了+8:00了。CST就是Central Standard Time的意思。但这样就造成了转换的不一致。我们应该使用CST标准才对。 让我们再看一下: >>> datetime.datetime.now(tz) datetime.datetime(2009, 2, 22, 11, 11, 2, 125000, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) >>> datetime.time(23, 18, 5, tzinfo=tz) datetime.time(23, 18, 5, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>) 可以看到now()函数得到的是CST的,而time传入tzinfo是LMT的。(date不支持tzinfo参数)所以我们要进行修订,怎么做,使用timezone对象的localize()方法,如: >>> d = datetime.datetime(2009,2,21,23,18,5) >>> tz.localize(d) datetime.datetime(2009, 2, 21, 23, 18, 5, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>) 所以我才明白pytz的文档上说的: Creating localtimes is also tricky, and the reason why working with local times is not recommended. Unfortunately, you cannot just pass a ‘tzinfo’ argument when constructing a datetime. 所以我的建议是生成带时区的时间时,一定要使用timezone.localize()来生成。不要在时间对象的构造函数中传入tzinfo的方式来实现,为些我封装了一些函数放在了uliweb/utils/date.py中。 另外关于北京时间。在pytz中,我无法找到Asia/Beijing和GMT+8这样的时区设置,但是有些时间转换的工具却有。按理说pytz使用的是标准的时区数据库,我特意下载了查看,的确是没有。 时区处理的确是挺麻烦的事。象有些数据库也支持这样的功能,如postgres支持set timezone的命令,这是在django中看到的。 |
最近读者: