Pytz在没有DST的情况下将时间转换为UTC

时间:2018-01-18 12:27:22

标签: python-3.x datetime utc dst pytz

在发布之前我做了很多研究,但我似乎无法正确转换。我有一些有时间戳的数据,有些已经应用了DST,有些则没有。我认为指定它没有DST的正确方法是使用pytz的is_dst参数。所有3个选项都提供与UTC相同的偏移量,这是不正确的。偏移量应为+1000。什么是进行此转换的最佳方法,为什么is_dst参数没有任何区别?

pytz_eastern.localize(datetime(2018, 1, 18, 18, 50), is_dst=None).strftime('%Y-%m-%d %H:%M %z')
'2018-01-18 18:50 +1100'
pytz_eastern.localize(datetime(2018, 1, 18, 18, 50), is_dst=False).strftime('%Y-%m-%d %H:%M %z')
'2018-01-18 18:50 +1100'
pytz_eastern.localize(datetime(2018, 1, 18, 18, 50), is_dst=True).strftime('%Y-%m-%d %H:%M %z')
'2018-01-18 18:50 +1100'

1 个答案:

答案 0 :(得分:1)

  

大多数时间戳都会忽略is_dst参数。它仅在DST过渡模糊期间用于解决这种模糊性。

您尝试通过忽略转换规则来转换日期时间。我不认为pytz会支持这一点。相反,您可以在标准时间内选择日期并询问其偏移量,然后使用它。

>>> from datetime import *
>>> import pytz
>>> pytz_eastern = pytz.timezone('Australia/Sydney')

utcoffset方法给出了特定日期时间的偏移量(dst方法也只给出了DST偏移量。)

>>> pytz_eastern.dst(datetime(2018, 6, 1))
datetime.timedelta(0)
>>> pytz_eastern.utcoffset(datetime(2018, 6, 1))
datetime.timedelta(0, 36000)

>>> pytz_eastern.dst(datetime(2018, 1, 1))
datetime.timedelta(0, 3600)
>>> pytz_eastern.utcoffset(datetime(2018, 1, 1))
datetime.timedelta(0, 39600)

从标准时间的日期获取utcoffset并直接使用日期时间的tzinfo kwarg进行设置,然后将其提供给pytz进行转换。

所以这是一个在时钟上显示的日期时间,该时间未针对夏令时进行调整:

>>> standard_offset = timezone(pytz_eastern.utcoffset(datetime(2018, 6, 1)))
>>> datetime(2018, 1, 18, 18, 50, tzinfo=standard_offset).strftime('%Y-%m-%d %H:%M %z')
'2018-01-18 18:50 +1000'

这就是同一个日期时间带回现实:

>>> datetime(2018, 1, 18, 18, 50, tzinfo=standard_offset).astimezone(pytz_eastern).strftime('%Y-%m-%d %H:%M %z')
'2018-01-18 19:50 +1100'

(标准偏移也似乎可以作为._utcoffset使用,但是没有记录,所以这是一个要求特定日期的utcoffset的理由,因为过去的偏移不太可能发生变化。)

事实上,由于pytz为您提供了计算的偏移量和当前的DST值,您可以减去这两个值以获得忽略DST的标准偏移量。

def add_forgotten_dst(dt, zoneinfo):
    '''Like pytz.localize, but ignores dst.'''
    utcoffset = zoneinfo.utcoffset(dt)
    dst = zoneinfo.dst(dt)
    standard_offset = utcoffset - dst
    dt = dt.replace(tzinfo=timezone(standard_offset))
    return dt.astimezone(zoneinfo)

>>> naive_time = datetime(2018, 1, 18, 18, 50)
>>> print(pytz_eastern.localize(naive_time))
2018-01-18 18:50:00+11:00
>>> print(add_forgotten_dst(naive_time, pytz_eastern))
2018-01-18 19:50:00+11:00