为什么这段代码:
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')
根据运行它的机器的时区返回不同的值?
根据我的理解,解析器返回没有时区的日期时间,然后分配tz,而不更改任何其他内容,最后将其转换为时间戳。我的本地tz不应该在任何地方使用。
答案 0 :(得分:2)
dateutil.parser
会附加一个时区,当且仅当它找到一个时区时,可能依赖于您的本地计算机时区设置,因为如果它检测到缩写的时区如“EST” “这是您当地时区的缩写列表,它将假设您的意思是。
那就是说,这不是这种情况下发生的事情。即使parser
附加了时区,datetime.replace
也会批量替换时区,而非转换。我不认为您的问题中有足够的信息可以完全诊断此问题,但如果timezone()
为pytz.timezone()
,则至少有一个问题是pytz
个时区不能使用datetime
附加到replace
个对象。您需要使用datetime_obj = pytz.timezone(tz_code).localize(datetime_obj)
。
请注意,localize
方法假定您有一个时区初始对象,因此如果datetutil
的解析器返回时区感知datetime
,它将引发错误,因此您应该将ignoretz=True
传递给解析器以防止这种情况。
尽管如此,即使你这样做,真正的问题在于你使用time.mktime
。请参阅this answer,这是完全相同的问题。总结一下这个答案,最好的办法是使用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())