Python - 在特定时区设置日期时间(不进行UTC转换)
为了说明清楚,这里使用的是 Python 2.6,我在用 pytz 库。
这个应用只处理美国的时区,我需要把今天的日期固定下来,然后获取今天晚上8点和11点在太平洋标准时间(PST)的 Unix 时间戳(也就是纪元时间)。
这让我快要抓狂了。
> pacific = pytz.timezone("US/Pacific")
> datetime(2011,2,11,20,0,0,0,pacific)
datetime.datetime(2011, 2, 11, 20, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:0 STD>)
> datetime(2011,2,11,20,0,0,0,pacific).strftime("%s")
'1297454400'
zsh> date -d '@1297454400'
Fri Feb 11 12:00:00 PST 2011
尽管我已经设置了时区,并且在创建日期时间的时候用了这个时区,但它还是把时间创建成了 UTC,然后再进行转换。这就麻烦了,因为 UTC 的时间会比我想要的时间提前一天,这样在计算的时候就出问题了。
有没有简单(或者至少合理)的方法来生成今天晚上8点 PST 的时间戳呢?
为了说明清楚,我确实明白在大多数情况下使用 UTC 的好处,比如数据库的时间戳或者一般存储。但这不是那种情况,我特别需要的是晚上在 PST 的时间戳,UTC 在这里不应该参与进来。
2 个回答
26
这里有两个问题:
- 你不应该直接把像
"US/Pacific"
这样的时区(它的UTC偏移量不是固定的)作为tzinfo参数传递。你应该使用pytz.timezone("US/Pacific").localize()
方法来处理。 .strftime('%s')
这个方法不太通用,它会忽略tzinfo,而且总是使用本地时区。建议使用datetime.timestamp()
或者在旧版本Python中的类似方法。
要在指定时区创建一个带时区的日期时间:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
tz = pytz.timezone("US/Pacific")
aware = tz.localize(datetime(2011, 2, 11, 20), is_dst=None)
要获取POSIX时间戳:
timestamp = (aware - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
(在Python 2.6中,可以查看 totimestamp()
函数,了解如何模拟 .total_seconds()
方法。)
23
首先,创建一个名为 utc
的 tzinfo 对象,用于表示 UTC 时区,然后可以尝试以下代码:
#XXX: WRONG (for any timezone with a non-fixed utc offset), DON'T DO IT
datetime(2011,2,11,20,0,0,0,pacific).astimezone(utc).strftime("%s")
补充:正如评论中提到的,将时区放入 datetime
构造函数中并不总是可靠的。更推荐的方法是参考 pytz 文档,可以这样做:
pacific.localize(datetime(2011,2,11,20,0,0,0)).astimezone(utc).strftime("%s")
另外,评论中还提到 strftime("%s")
这个方法并不可靠,它会 忽略 时区信息(即使是 UTC),而是根据运行它的系统的时区来处理。这个方法依赖于底层的 C 库实现,在某些系统上(比如 Windows)根本无法使用。