Python3中datetime不同时区转换介绍与踩坑

最近的项目需要根据用户所属时区制定一些特定策略,学习、应用了若干python3的时区转换相关知识,这里整理一部分记录下来。

下面涉及的几个概念及知识点:

GMT时间:Greenwich Mean Time, 格林尼治平均时间

UTC时间:Universal Time Coordinated 世界协调时,可以认为是更精准的GMT时间,但两者误差极小,在1s以内,一般可视为等同

LMT:Local Mean Time, 当地标准时间

Python中的北京时间:Python的标准timezone中信息中并没有Asia/Beijing,原因要追溯到国民政府期间上报给国际标准的五个时区城市没有北京,因此一般使用Asia/Shanghai获取东8区时间

Python使用到的时间相关函数及概念:

包含时区信息的datetime称为: offset-aware datetime,反之称为offset-naive datetime

pytz.timezone(x): pytz package中预定义的时区相关对象, pytz可通过 python3 -m pip install pytz 安装

datetime(…) : 直接指定year/month/day/hour/second生成naive datetime

datetime(…tzinfo=tz) : 直接指定year/month/day/hour/second+时区信息生成offset-aware datetime

datetime.now(): 生成当前默认时区的 naive datetime

datetime.now(tzinfo=tz): 生成指定时区的offset-aware datetime

datetime.strptime(string, format) : 生成当前默认时区的string、format表示的 naive datetime

datetime.replace(tzinfo=tz): 直接替换datetime 时区信息为tz时区offset-aware datetime–不针对时区进行任何转换

datetime.astimezone(tz): 将时间转换为新的tz时区的offset-aware datetime

下述代码示例中,由于云主机位于日本,所以默认时区为东9区(Asia/Tokyo)

Python中获取当前时刻时间:

可以看到,datetime.now()未指定时区时,获取到的对象是offset-navie datetime,而指定时区后则是offset-aware datetime,naive和aware的datetime是不可以执行比较、相减相关操作的,只有同类型的datetime才能求时间差值、比较大小,如下:

这里碰到了第一个坑,比如我们想获得北京时间2021年1月1日0点的datetime,然后将其转换为东京时间,直觉上我们很可能这么写:

仔细一看,北京时间的0点转化为东京时间却是0:54,相差是54分钟,而不是1个小时,这就奇怪了,仔细一看tzinfo中的信息是LMT+8:06:00 STD,表示这是LMT时间,相比UTC快8小时6分钟,而不是东8区标准时间,而通过astimezone方法转换后得到的就是日本标准时间(东9区),所以两者之前的差值并不是1小时整。

第一个坑究其原因,通过datetime(..tzinfo=..)指定时区获取的是LMT,而datetime.now(tz)、datetime.astimezone(tz) 获取的却是UTC(GMT)标准时间,LMT和GMT标准时间可能会有甚至十分钟级的差值,这已经足够影响到程序的正常逻辑了。

所以如果要保证获取标准时区的时间,建议避免使用Asia/Shanghai、Asia/Tokyo这类大洲/城市 字符串表示时间,而使用GMT、UTC这些无歧义的标准时区,如下:

这里第二个坑出现了,由于历史原因,Python中timezone的表示中,时区偏移以西为正,以东为负,和我们熟悉的ISO标准刚好相反,所以东9区应该表示为Etc/GMT-9, 而Etc/GMT+9表示的其实是西9区,如下可以验证GMT-9与JST相差0, GMT+9与JST相差18小时(64800s):

最后,获取指定时区2021年1月1日datetime的方式,以北京时间为例:

进一步如果要获取指定时区零点的时间戳就很简单了:

另外两种获取指定时区时刻的方法,此三种方式彼此等价:

参考资料:

Original: https://www.cnblogs.com/AcAc-t/p/python3_datetime_timezone.html
Author: 及时
Title: Python3中datetime不同时区转换介绍与踩坑

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/643582/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球