python – 使用pytz的Datetime时区转换
作者:互联网
这只是关于pytz的另一篇文章.
有两个函数可以在两个时区之间转换日期时间对象.第二个功能适用于所有情况.第一个函数在两种情况下失败,(3)和(4).类似的SO post没有像这样的问题.任何基于localize(datetime.datetime)和replace(tzinfo)之间差异的解释都将是一个很大的帮助.
>>> from dateutil.parser import parse
>>> import pytz
第一个功能(越野车)
下面的函数使用datetime.datetime.replace(tzinfo).
def buggy_timezone_converter(input_dt, current_tz='UTC', target_tz='US/Eastern'):
'''input_dt is a datetime.datetime object'''
current_tz = pytz.timezone(current_tz)
target_tz = pytz.timezone(target_tz)
target_dt = input_dt.replace(tzinfo=current_tz).astimezone(target_tz)
return target_tz.normalize(target_dt)
现在注意四个日期时间转换.
(1)从UTC到EST – 好的
>>> buggy_timezone_converter(parse('2013-02-26T04:00:00'))
Out[608]: datetime.datetime(2013, 2, 25, 23, 0, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)
(2)从UTC到EDT – 好的
>>> buggy_timezone_converter(parse('2013-05-26T04:00:00'))
Out[609]: datetime.datetime(2013, 5, 26, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
(3)从EST到UTC – 不行.时间偏移是4小时56分钟.它应该是5个小时
>>> buggy_timezone_converter(parse('2013-02-26T04:00:00'), target_tz='UTC', current_tz='US/Eastern')
Out[610]: datetime.datetime(2013, 2, 26, 8, 56, tzinfo=<UTC>)
(4)从EDT到UTC – 不行.时间偏移是4小时56分钟.它应该是4个小时.不考虑夏令时.
>>> buggy_timezone_converter(parse('2013-05-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[611]: datetime.datetime(2013, 5, 26, 8, 56, tzinfo=<UTC>)
第二功能(完美工作)
下面的函数使用pytz.timezone.localize(datetime.datetime).它完美地运作
def good_timezone_converter(input_dt, current_tz='UTC', target_tz='US/Eastern'):
current_tz = pytz.timezone(current_tz)
target_tz = pytz.timezone(target_tz)
target_dt = current_tz.localize(input_dt).astimezone(target_tz)
return target_tz.normalize(target_dt)
(1)从UTC到EST – 好的
>>> good_timezone_converter(parse('2013-02-26T04:00:00'))
Out[618]: datetime.datetime(2013, 2, 25, 23, 0, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)
(2)从UTC到EDT – 好的
>>> good_timezone_converter(parse('2013-05-26T04:00:00'))
Out[619]: datetime.datetime(2013, 5, 26, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
(3)从EST到UTC – 好的.
>>> good_timezone_converter(parse('2013-02-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[621]: datetime.datetime(2013, 2, 26, 9, 0, tzinfo=<UTC>)
(4)从EDT到UTC – 好的.
>>> good_timezone_converter(parse('2013-05-26T04:00:00'), current_tz='US/Eastern', target_tz='UTC')
Out[620]: datetime.datetime(2013, 5, 26, 8, 0, tzinfo=<UTC>)
解决方法:
我假设你有这些问题:
>为什么第一个函数适用于UTC时区?
>为什么“US / Eastern”时区(DstTzInfo实例)失败?
>为什么第二个函数适用于所有提供的示例?
第一个函数不正确,因为它使用d.replace(tzinfo = dsttzinfo_instance)而不是dsttzinfo_instance.localize(d).
第二个函数在大多数情况下是正确的,除非在模糊或不存在的时间期间,例如,在DST转换期间 – 您可以通过将is_dst参数传递给.localize()来更改行为:False(默认)/ True / None(引发例外).
第一个函数适用于UTC时区,因为它对任何日期都有固定的utc偏移量(零).其他时区如America / New_York可能在不同的时间有不同的utc偏移(夏令时,战争时间,任何一些当地政客可能认为是个好主意的时间 – 它可以是任何东西 – tz数据库在大多数情况下有效).要实现tzinfo.utcoffset(dt),tzinfo.tzname(dt),tzinfo.dst(dt)方法,pytz使用DstTzInfo实例的集合,每个实例都具有不同的(_tzname,_utcoffset,_dst)属性集.给定dt(日期/时间)和is_dst,.localize()方法从集合中选择适当的(在大多数情况下但不总是)DstTzInfo实例. pytz.timezone(‘America / New_York’)返回一个DstTzInfo实例,其中包含(_tzname,_utcoffset,_dst)属性,这些属性对应于某些未记录的时刻(不同的pytz版本可能返回不同的值 – 当前版本可能返回对应的tzinfo实例到zoneinfo可用的最早日期 – 你大部分时间都不想要这个值:我认为选择默认值背后的动机是突出显示错误(将pytz.timezone传递给datetime构造函数或.replace () 方法).
总结一下:.localize()选择适当的utcoffset,tzname,dst值,.replace()使用默认(不合适)值. UTC只有一组utcoffset,tzname,dst因此可以使用默认值,而.replace()方法与UTC时区一起使用.您需要传递datetime对象和is_dst参数,以便为其他时区选择适当的值,例如“America / New_York”.
原则上,pytz可以调用localize()方法实现utcoffset(),tzname(),dst()方法,即使dt.tzinfo == self:它会使这些方法O(log n)及时n为数字具有不同(utcoffset,tzname,dst)值的间隔但是datetime构造函数和.replace()将按原样工作,即显式localize()调用仅在传递is_dst时是必需的.
标签:pytz,python,timezone,datetime,python-2-7 来源: https://codeday.me/bug/20190916/1807785.html