我刚刚注意到这一点,我完全困惑为什么会发生这种情况,以及如何防止它。
我使用的计算机是 Windows 10,安装在哥本哈根市。我的平台是这样的:
$ for ix in "uname -s" "python3 --version"; do echo "$ix: " $($ix); done
uname -s: MINGW64_NT-10.0-19045
python3 --version: Python 3.11.9
由于我在 MINGW64 下使用
bash
终端,因此我还在 .bashrc
中为 python3 设置了别名:
alias python3="winpty python3"
好的;所以现在我想通过在 bash 终端中调用
tzlocal.get_localzone()
命令来打印 python3
:
$ python3 -c 'import tzlocal; print(tzlocal.get_localzone())'
Europe/Copenhagen
太好了,我得到了预期的时区。然而,回想一下这里的
python3
实际上是winpty python3
;为了测试 just python3
,让我们在命令前面添加一个反斜杠,以逃避 bash
别名:
$ \python3 -c 'import tzlocal; print(tzlocal.get_localzone())'
Europe/Paris
太棒了——我从来没想到会这样;我到底为什么会来到巴黎,而不是哥本哈根(这就是该计算机上的 Windows 10 本身的设置目的)?
我的意思是,就时区而言,这并不是那么遥远 - 但当明显有条件使其输出正确的时区时,为什么要满足于更少呢?
那么,为什么会发生这种情况 - 我怎样才能让
\python3
运行 tzlocal.get_localzone()
也返回欧洲/哥本哈根?
编辑:通过在两种情况下打印
os.environ
,可以看到 winpty
python 环境定义了一个环境变量 'TZ': 'Europe/Copenhagen' - 而直接 python 环境没有这样的变量。
这里的关键是您尝试将 Windows 时区名称映射到 IANA 数据库名称(tzlocal 为您提供的名称)。这是很脆弱的——IANA 和 MS 之间没有就这一点应该明确达成一致。
tzlocal
为此依赖于社区的努力。
在 Windows 上,如果我将 tz 设置为哥本哈根,Windows 会在内部使用“浪漫标准时间”(目前;2024-04-18)。您可以通过在终端中运行
tzutil /g
进行检查。如果您检查我上面链接的 XML 文件,第一个映射是...“欧洲/巴黎”。下面还列出了“欧洲/哥本哈根”。这两个时区遵循相同的规则 AFAIK,因此映射是“OK”(就 UTC 偏移量而言是正确的),但并不完美。