为什么这段代码依赖于我的本地机器时区?

Why is this code dependant on my local machine timezone?

为什么这个代码:

def parse_date(datetime_string, tz_code):
    tz = timezone(tz_code)
    datetime_obj = parser.parse(datetime_string)
    datetime_obj_localized = datetime_obj.replace(tzinfo=tz)
    return time.mktime(datetime_obj_localized.timetuple())


def test_parse_date(self):
   self.assertEquals(1482951600, parse_date('2016-12-28 14:00', 'US/Eastern')

returns 一个不同的值取决于运行所在机器的时区?

在我的理解中,解析器 returns 一个没有时区的日期时间,然后它分配一个 tz,不改变任何其他东西,最后它被转换成一个时间戳。我本地的tz 哪里都用不了。

dateutil.parser 将附加一个时区当且仅当它找到一个时区,这 可能 取决于您本地机器的时区设置,因为如果它检测到一个缩写像 "EST" 这样的时区在您当地时区的缩写列表中,它会假设这就是您的意思。

也就是说,这不是本例中发生的情况。即使 parser 附加了时区,datetime.replace 也会对时区进行批量替换,而不是转换。我认为您的问题中没有足够的信息来完全诊断此问题,但如果 timezone()pytz.timezone(),至少您的问题之一是 pytz 时区不能使用 replace 附加到 datetime 个对象。您需要改为使用 datetime_obj = pytz.timezone(tz_code).localize(datetime_obj).

请注意,localize 方法假定您有一个时区初始对象,因此如果 datetutil 的解析器 returns 时区感知 datetime,因此您应该将 ignoretz=True 传递给解析器以防止出现这种情况。

也就是说,即使您这样做了,真正的问题还是在于您对 time.mktime 的使用。见,完全一样的问题。总结一下这个答案,最好的办法是使用 calendar.timegm 而不是 mktime,并在调用它之前转换为 UTC。结合我的建议,这是您的代码的更新版本:

import calendar
from dateutil.tz import tzutc

def parse_date(datetime_string, tz_code):
    tz = timezone(tz_code)
    datetime_obj = parser.parse(datetime_string, ignoretz=True)
    datetime_obj_localized = tz.localize(datetime_obj)

    datetime_obj_utc = datetime_obj_localized.astimezone(tzutc())
    return calendar.timegm(datetime_obj_utc.timetuple())