记一次 Python 项目全量替换至 UTC 时区的重构经历(中)

2023-11-29 19:48:33 浏览数 (2)

0x00.TL;DR

  • datetime.fromtimestamp() -> datetime.utcfromtimestamp()

0x01.前言

上一篇文章中介绍了生成时间的格式汇总,本文将介绍将时间字符串转换为 Python 对象也就是解析的部分

0x02.解析时间的格式汇总

代码中主要有 2 种

  1. 解析时间戳,比如解析至 datetime 对象
代码语言:python代码运行次数:0复制
>>> import datetime
>>> datetime.datetime.fromtimestamp(1701171876.286261)
datetime.datetime(2023, 11, 28, 19, 44, 36, 286261)
  1. 解析时间字符串,比如解析至 struct_time 对象
代码语言:python代码运行次数:0复制
>>> my_time_str = '2023-11-28 19:44:36'
>>> my_time_obj = time.strptime(my_time_str, '%Y-%m-%d %H:%M:%S')
>>> my_time_obj
time.struct_time(tm_year=2023, tm_mon=11, tm_mday=28, tm_hour=19, tm_min=44, tm_sec=36, tm_wday=1, tm_yday=332, tm_isdst=-1)

0x03.解析时间戳类型

datetime.fromtimestamp() -> datetime.utcfromtimestamp()

前者返回的是本地时间的 datetime 对象,需要切换至 UTC 时间的 datetime 对象

代码语言:python代码运行次数:0复制
>>> datetime.datetime.utcfromtimestamp(1701171876.286261)
datetime.datetime(2023, 11, 28, 11, 44, 36, 286261)

阅读文档可知可以用 datetime.utcfromtimestamp()

0x04.解析时间字符串类型

1. time.strptime(),返回 struct_time,无需修改

2. yaml.load,没想到吧。用 yaml 可以将 c: 2023-11-23 02:40:00 这种 yaml 格式的字符串解析成如下字典

{'c': datetime.datetime(2023,11,23,2,40)}

代码语言:javascript复制
>>> import yaml
>>> a = 'c: 2023-11-23 02:40:00'
>>> b = yaml.safe_load(a)
>>> b
{'c': datetime.datetime(2023, 11, 23, 2, 40)}
>>> d = b['c']
>>> d
datetime.datetime(2023, 11, 23, 2, 40)
>>> print(d.tzinfo)
None
>>> d.timestamp()
1700678400.0

最后一步转换时间戳,是默认 d 是本地时区的 datetime 对象,所以转换后就多减了 8 个小时

可以引入 pytz 库,强制替换其时区至 UTC,问题就解决了

代码语言:javascript复制
>>> import pytz
>>> e = d.replace(tzinfo=pytz.UTC)
>>> e
datetime.datetime(2023, 11, 23, 2, 40, tzinfo=<UTC>)
>>> e.timestamp()
1700707200.0

0x05.额外 1——tm_gmtoff

代码中还有用到过 tm_gmtoff,查阅文档可知其是与 UTC 时区的差值

比如 UTC 8 就差了 8 个小时,也就是 8 * 3600 = 28800s

代码语言:javascript复制
>>> time.localtime().tm_gmtoff
28800
代码语言:javascript复制
>>> time.gmtime().tm_gmtoff
0

下文代码是先获取服务器的时区,然后追加至 start & end

但如果统一都使用 UTC 的话,就不用再追加了,L52 行可以删除

0x06.后记

最近 2 篇文章介绍了代码中操作生成时间和解析时间,下一篇文章会介绍第三方组件——数据库的时区设置

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

DAY 2/3

0 人点赞