python datetime.astimezone行为不正确?

时间:2015-09-03 11:13:31

标签: python pytz python-datetime python-dateutil

这是首先从IST中的字符串解析时间然后将其转换为UTC的代码。因此,当它在印度下午4点时,GMT / UTC的时间是上午10:30。以下代码将其打印为晚上9:30。因此,它不是减去偏移量而是添加偏移量。从python文档https://docs.python.org/2/library/datetime.html#datetime.datetime.astimezone astimezone的示例实现来看,如果它是负数,它似乎会添加偏移,但它似乎与它应该做的相反。文档说它调整UTC时间保持相同的时间,但是在传递的时区的本地时间,这与示例实现相反。

from dateutil.parser import parse
from pytz import timezone

d = parse('Tue Sep 01 2015 16:00:00 GMT+0530')

# Prints datetime.datetime(2015, 9, 1, 16, 0, tzinfo=tzoffset(None, -19800))
print d

utc = timezone('UTC')

# Prints datetime.datetime(2015, 9, 1, 21, 30, tzinfo=<UTC>)
print d.astimezone(utc)

我不确定是什么问题。它是astimezone或文档的实现还是偏移本身的符号反转了?

2 个答案:

答案 0 :(得分:2)

astimezone()是正确的。 parse()不正确或输入不明确。 parse()GMT+0530解释为已弃用的POSIX样式GMT+h时区格式,其中utc偏移符号相反。见Timezone offset sign reversed by Python dateutil?

要解决此问题,请使用相反的符号:

>>> from dateutil.parser import parse
>>> d = parse('Tue Sep 01 2015 16:00:00 GMT+0530')
>>> utc = d.replace(tzinfo=None) + d.utcoffset() #NOTE: the opposite sign
>>> utc
datetime.datetime(2015, 9, 1, 10, 30)

如果输入可能是明确的(当parse()返回正确的结果时),那么您不应该手动更改utc偏移符号。您可以删除时区并重新应用它:

>>> import pytz
>>> tz = pytz.timezone('Asia/Kolkata')
>>> tz.localize(parse('Tue Sep 01 2015 16:00:00 GMT+0530').replace(tzinfo=None), is_dst=None)
datetime.datetime(2015, 9, 1, 16, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>)
>>> _.astimezone(pytz.utc)
datetime.datetime(2015, 9, 1, 10, 30, tzinfo=<UTC>)

对于模糊或不存在的时间(在DST过渡期间),它可能会失败。如果您知道输入是GMT+h格式,那么请使用第一个代码示例并手动转换为UTC。

答案 1 :(得分:0)

以下代码段工作正常。

>>> d = parse('Tue Sep 01 2014 16:00:00 GMT+0530')
>>> ind = timezone('Asia/Kolkata')
>>> d=d.replace(tzinfo=ind)
>>> d
datetime.datetime(2015, 9, 1, 16, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' LMT+5:53:00 STD>)
>>> utc = timezone('UTC')
>>> d.astimezone(utc)
datetime.datetime(2015, 9, 1, 10, 7, tzinfo=<UTC>)

此处我更改了tzinfo格式中使用的pytz。确保所有时区都采用pytz格式。

虽然,我不知道为什么IST是LMT + 5:53:00。发现多年来的偏移变化,长时间使用+5:53,但现在我们使用+5:30。但坦率地说,我对此并不太了解。