Pytz 在没有 DST 的情况下将时间转换为 UTC
Pytz convert time to UTC without 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'
The is_dst
parameter is ignored for most timestamps. It is only used during DST transition ambiguous periods to resolve that ambiguity.
您试图通过忽略转换规则来转换日期时间。我认为 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,直接用datetime的tzinfo
kwarg设置,然后才给pytz进行转换。
所以这是一个未针对 DST 调整的时钟上显示的日期时间:
>>> 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
我在发布这篇文章之前做了很多研究,但我似乎无法正确转换。我有一些具有时间戳的数据,一些应用了夏令时,而另一些则没有。我认为指定它没有 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'
The
is_dst
parameter is ignored for most timestamps. It is only used during DST transition ambiguous periods to resolve that ambiguity.
您试图通过忽略转换规则来转换日期时间。我认为 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,直接用datetime的tzinfo
kwarg设置,然后才给pytz进行转换。
所以这是一个未针对 DST 调整的时钟上显示的日期时间:
>>> 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