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

2023-11-29 18:46:53 浏览数 (2)

0x00.TL;DR

  • time.mktime() -> import calendar calendar.timegm()
  • time.localtime() -> time.gmtime()
  • datetime.datetime.now() -> datetime.datetime.utcnow()

0x01.前言

目前测试环境中 VM 的时区全是 Asia/Shanghai(即 CST:GMT 8),但是可能会部署至非 CST 时区的地域,前端显示会有问题

经上层决策后决定将项目中的时区全部改成 UTC(即 GMT 0),前后端统一都用 UTC。于是撸起袖子开干

0x02.生成时间的格式汇总

代码中主要有 3 种

  • 1. 时间戳类型,比如官方 time 库中 time.time() 的输出
代码语言:python代码运行次数:0复制
>>> time.time()
1701171876.286261
  • 2. 时间对象类型,比如官方 time 库和 datetime 库中的时间对象
  • 3. 时间字符串类型,比如官方 time 库中 time.strftime() 的输出
代码语言:python代码运行次数:0复制
>>> time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
'2023-11-28 19:44:36'

以上两种格式都需要统一至 UTC,上述只举例了 time 库,但实际项目中还用到了官方 datetime 库,需要仔细搜索

0x03.重构时间戳类型

1. time.time(),阅读文档可知已经是 UTC 的时间戳,无需转换

参照上文中的输出,UTC 时间是 11:44:36,木有问题

2. time.mktime() -> calendar.timegm()

2.1 举个栗子 1,如下 start_time 的取法可以直接使用 time.time() 替换

原来的方法是先创建 datetime 对象,然后转换至 UTC 的时间戳,太麻烦了重构掉

2.2 举个栗子 2,如下 start_time 的取法就需要使用 calendar.timegm() 替换

因 time.mktime() 是 local_time 的反函数,也就是传入的 struct_time 经过转换会变成 localtime 对应的时间戳,需要修改

阅读文档可知可以用 import calendar calendar.timegm(),它返回的是 UTC 对应的时间戳

0x04.重构时间对象类型

1. time.localtime() -> time.gmtime()

代码语言:python代码运行次数:0复制
>>> time.localtime()
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=0)

本地时间的 struct_time,需要切换至 UTC 时间的 struct_time

代码语言:python代码运行次数:0复制
>>> time.gmtime()
time.struct_time(tm_year=2023, tm_mon=11, tm_mday=28, tm_hour=11, tm_min=44, tm_sec=36, tm_wday=1, tm_yday=332, tm_isdst=0)

阅读文档可知可以用 time.gmtime()

2. datetime.datetime.now() -> datetime.datetime.utcnow()

代码语言:python代码运行次数:0复制
>>> datetime.datetime.now()
datetime.datetime(2023, 11, 28, 20, 34, 3, 121237)

本地时间的 datetime 对象,需要切换至 UTC 时间的 datetime 对象

代码语言:python代码运行次数:0复制
>>> datetime.datetime.utcnow()
datetime.datetime(2023, 11, 28, 12, 34, 3, 121237)

阅读文档可知用 datetime.utcnow()

0x05.重构时间字符串类型

1. time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())

将其中的 time.localtime() 替换至 time.gmtime() 是最简便的方法

也就是 time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())

2. datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

本着能用 time 库就不用 datetime 库的原则,替换至 time 库

同样替换装 time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())

3. 关于 datetime 库的使用,有的仓库是 import datetime,而有的则是 from datetime import datetime,针对后者 datetime.now().strftime('%Y-%m-%d %H:%M:%S')

同样替换至 time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())

0x06.后记

实际替换时,按照关键字搜索即可

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

DAY 1/3

0 人点赞