Python的时区会让很多人困惑。我就曾经在Alpine的Docker容器中使用Django时遇到时区总是UTC导致了某些情况下日期格式化时产生了相差一天的问题。
这篇记录尽量通过详细的说明来解释过程中的所有细节问题。希望读者能够由此理解Python的时区管理以及Django的时区机制。
首先说一下Alpine Docker镜像中的时区
在Python的官方镜像中python:alpine没有设置时区,缺省是标准时区UTC。
# date
Sat Nov 9 05:25:09 UTC 2019
# # UTC表示标准时间
其他时区信息需要通过apk安装tzdata。为了保证镜像尽可能的小,缺省是不安装这个包的。
# apk --update add --no-cache tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2019c-r0)
Executing busybox-1.30.1-r2.trigger
OK: 21 MiB in 36 packages
安装完成后系统将所有时区信息存放在了/usr/share/zoneinfo/目录下
# ls /usr/share/zoneinfo/
Africa CET Egypt GMT+0 Iran MST7MDT Poland UTC zone.tab
America CST6CDT Eire GMT-0 Israel Mexico Portugal Universal zone1970.tab
Antarctica Canada Etc GMT0 Jamaica NZ ROC W-SU
Arctic Chile Europe Greenwich Japan NZ-CHAT ROK WET
Asia Cuba Factory HST Kwajalein Navajo Singapore Zulu
Atlantic EET GB Hongkong Libya PRC Turkey iso3166.tab
Australia EST GB-Eire Iceland MET PST8PDT UCT posixrules
Brazil EST5EDT GMT Indian MST Pacific US right
其中/usr/share/zoneinfo/Asia/Shanghai这个文件是北京时间。我们将它复制到/etc/localtime文件。(/etc/localtime这个文件缺省也是没有的)。
# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# date
Sat Nov 9 13:36:15 CST 2019
# # 这时我们看到系统的时区信息从UTC变为CST,这就是中国时区了
然后清理安装的时区文件。由于Docker镜像要尽可能的小,所以一些用不到的文件需要删除掉(这也是缺省镜像中不包含时区文件的原因)
# apk del tzdata
(1/1) Purging tzdata (2019c-r0)
Executing busybox-1.30.1-r2.trigger
OK: 18 MiB in 35 packages
#
# ls /usr/share/zoneinfo
ls: /usr/share/zoneinfo: No such file or directory