Python - 从 DST 调整的本地时间到 UTC
Posted
技术标签:
【中文标题】Python - 从 DST 调整的本地时间到 UTC【英文标题】:Python - From DST-adjusted local time to UTC 【发布时间】:2011-10-11 16:48:16 【问题描述】:某家银行在全球所有主要城市都设有分行。它们都在当地时间上午 10:00 开放。如果在使用 DST 的时区内,那么当地的开放时间当然也遵循 DST 调整的时间。那么我如何从本地时间转到UTC时间。
我需要的是这样的函数to_utc(localdt, tz)
:
参数:
localdt:本地时间,作为天真的日期时间对象,经过 DST 调整 tz:TZ 格式的时区,例如“欧洲/柏林”返回:
日期时间对象,UTC,时区感知编辑:
最大的挑战是检测本地时间是否在一个有夏令时的时段,这也意味着它是夏令时调整的。
对于夏季 +1 DST 的“欧洲/柏林”:
1 月 1 日 10:00 => 1 月 1 日 9:00 UTC 7 月 1 日 10:00 => 7 月 1 日 8:00 UTC对于没有 DST 的“非洲/拉各斯”:
1 月 1 日 10:00 => 1 月 1 日 9:00 UTC 7 月 1 日 10:00 => 7 月 1 日 9:00 UTC【问题讨论】:
陷阱:2011 年 3 月 27 日 01:00,时钟被调到 02:00。所以 01:00 和 02:00 之间的时间间隔是无效的。 2011 年 10 月 30 日 01:00,时钟将调回 00:00。所以 00:00 和 01:00 之间的时间间隔是不明确的。pytz
描述了 DST 转换不适用于任何具有时区的时区。如果专门为帮助处理时区而构建的软件包不支持这一点,那么您自己做正确的工作就太多了。你必须满足于几乎正确。
【参考方案1】:
使用pytz,尤其是它的localize method:
import pytz
import datetime as dt
def to_utc(localdt,tz):
timezone=pytz.timezone(tz)
utc=pytz.utc
return timezone.localize(localdt).astimezone(utc)
if __name__=='__main__':
for tz in ('Europe/Berlin','Africa/Lagos'):
for date in (dt.datetime(2011,1,1,10,0,0),
dt.datetime(2011,7,1,10,0,0),
):
print('tz:15 l --> u'.format(
tz=tz,
l=date.strftime('%b %d %H:%M'),
u=to_utc(date,tz).strftime('%b %d %H:%M %Z')))
产量
Europe/Berlin Jan 01 10:00 --> Jan 01 09:00 UTC
Europe/Berlin Jul 01 10:00 --> Jul 01 08:00 UTC
Africa/Lagos Jan 01 10:00 --> Jan 01 09:00 UTC
Africa/Lagos Jul 01 10:00 --> Jul 01 09:00 UTC
【讨论】:
注意:有些当地时间是不明确的。尽管在 DST 过渡期间银行不太可能同时开张;你可以使用is_dst=None
参数.localize()
来断言。【参考方案2】:
from datetime import datetime, tzinfo, timedelta
class GMT1(tzinfo):
def utcoffset(self, dt):
return timedelta(hours=1)
def dst(self, dt):
return timedelta(0)
def tzname(self,dt):
return "Europe/Prague"
year, month, day = 2011, 7, 23
dt = datetime(year, month, day, 10)
class UTC(tzinfo):
def utcoffset(self, dt):
return timedelta(0)
def dst(self, dt):
return timedelta(0)
def tzname(self,dt):
return "UTC"
def utc(localt, tz):
return localt.replace(tzinfo=tz).astimezone(UTC())
print utc(dt, GMT1())
新版本。这可以满足您的要求 - 采用原始日期时间和时区并返回 UTC 日期时间。
【讨论】:
您的解决方案未能解决主要挑战:自动处理夏令时。 我不确定我是否理解。如果您使用的tzinfo
有一个timedelta
用于夏令时,它应该由utcnow()
自动处理?
我现在明白了。更新了我的答案。
仍然不确定这如何解决 DST 问题。七月的布拉格应该在 UTC+2(包括 DST)。您仍然为 GMT1
中的 dst 返回 timedelta(0)
:确实适用于 GMT+1,但这不是“欧洲/布拉格”的时区。以上是关于Python - 从 DST 调整的本地时间到 UTC的主要内容,如果未能解决你的问题,请参考以下文章
让 mktime() 在 C++ 中忽略 DST 和本地时区
org.joda.time |夏令时 (DST) 和本地时区偏移
Python,Pandas:tz_localize AmbiguousTimeError:无法用非 DST 日期推断 dst 时间