Docker环境下Python 2.7时区处理异常问题排查
Python 2.7容器化时区处理异常问题
问题背景
需要将Python 2.7代码库容器化,且无法升级至Python 3。本地Mac环境中Python 3.9.6运行时区相关逻辑正常,但基于Ubuntu镜像容器化后出现时区处理异常:
python:2.7.18-buster镜像可正常运行,但该镜像已3年未更新,存在安全风险;- 使用
ubuntu:18.04或ubuntu:16.04镜像时,切换时区后小时数无变化,时间戳也不符合预期。
复现代码
import os import datetime import time from dateutil.parser import parse date_string="2021-01-01" os.environ.get("TZ") # 预期为None,使用系统默认时区UTC print ("UTC Hour: ", datetime.datetime.now().hour) # 预期输出UTC当前小时 os.environ["TZ"] = "America/New_York" print ("NY Hour:", datetime.datetime.now().hour) # 预期输出EST当前小时 print (time.mktime(parse(date_string).timetuple())) # 预期结果:1609477200.0 os.environ["TZ"] = "Europe/London" print ("London Hour: ", datetime.datetime.now().hour) # 预期输出GMT当前小时 print (time.mktime(parse(date_string).timetuple())) # 预期结果:1609459200.0
问题原因
- Python 2.7的
datetime.now()不会自动监听TZ环境变量的动态修改,必须调用time.tzset()让系统重新加载时区配置; - Ubuntu基础镜像默认未安装完整的时区数据库
tzdata,导致时区切换指令无法生效。
解决方案
1. 完善Dockerfile,安装时区数据库
在构建Ubuntu镜像的Dockerfile中添加以下指令,确保时区数据完整:
RUN apt-get update && apt-get install -y --no-install-recommends tzdata \ && rm -rf /var/lib/apt/lists/*
2. 修改代码,动态切换时区后刷新配置
每次设置TZ环境变量后,调用time.tzset()刷新系统时区,修改后的代码如下:
import os import datetime import time from dateutil.parser import parse date_string="2021-01-01" print ("UTC Hour: ", datetime.datetime.now().hour) # 输出UTC当前小时 os.environ["TZ"] = "America/New_York" time.tzset() # 刷新时区配置 print ("NY Hour:", datetime.datetime.now().hour) # 输出EST当前小时 print (time.mktime(parse(date_string).timetuple())) # 正确输出1609477200.0 os.environ["TZ"] = "Europe/London" time.tzset() # 再次刷新时区配置 print ("London Hour: ", datetime.datetime.now().hour) # 输出GMT当前小时 print (time.mktime(parse(date_string).timetuple())) # 正确输出1609459200.0
3. 可选:设置固定系统时区
如果无需动态切换时区,可在Dockerfile中直接设置系统默认时区,避免代码中动态修改的操作:
ENV TZ=UTC RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
内容的提问来源于stack exchange,提问作者Anonymouslemming
相关产品推荐
相关产品推荐

