免责声明 1:仅在 GNU/Linux 上使用 glibc 进行了测试。在 Windows、macOS、具有非 GNU libc 的 Linux 和其他操作系统上,您的里程可能会有所不同。
免责声明 2:我在 Alpine Linux 上使用 musl libc 进行了测试,但它不起作用。使用 Docker 时您可能会遇到这种情况,因为 Alpine 在制作极简容器镜像方面非常受欢迎。
tl;博士
使用这个:
import locale
locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(("LC_TIME",)))
问题
@ShadowRanger 的 comment 引起了我的注意:
鉴于the strftime/strptime docs 中en_US 的“区域设置适当时间”以24 小时时钟呈现(%X 在en_US 区域设置下产生21:30:00),我怀疑Python 区域设置信息是否表明当地标准是 12 或 24 小时制。美国几乎 100% 是 12 小时制,但语言环境时间表示为 24 小时。
让我们试着找出这里发生了什么。
locale.getdefaultlocale() 函数的文档给了我们一个提示:
根据 POSIX,未调用 setlocale(LC_ALL, '') 的程序使用可移植的 'C' 语言环境运行。
看起来CPython默认使用'C'语言环境,它的时间表示似乎是24小时:
$ LC_TIME=C date
Tue Oct 27 13:06:54 UTC 2020
$ LC_TIME=en_US.UTF-8 date
Tue Oct 27 01:06:54 PM UTC 2020
$ TZ=UTC LC_TIME=de_DE.UTF-8 date
Di 27. Okt 13:06:54 UTC 2020
让我们确认一下:
$ LC_TIME=en_US.UTF-8 python3
>>> import locale
>>> import time
>>> locale.getlocale(locale.LC_TIME)
(None, None)
>>> time.strftime("%p")
'PM'
>>> time.strftime("%X")
'13:03:34'
>>> locale.setlocale(locale.LC_TIME, 'C')
'C'
>>> locale.getlocale(locale.LC_TIME)
(None, None)
这里我们可以看到两件事:
- 取消默认区域设置与将其设置为
'C' 相同。
- 设置
LC_TIME 环境变量而不在 Python 中显式使用它不会产生任何效果。
我想知道如果%X 不使用它,为什么会设置%p? ?️
解决方案
为了让程序尊重我们的区域设置偏好,我们需要调用locale.setlocale() 并提供LC_TIME。
$ LC_TIME=en_US.UTF-8 python3
>>> import locale
>>> import time
>>> locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(('LC_TIME',)))
'en_US.UTF-8'
>>> time.strftime("%p")
'PM'
>>> time.strftime("%X")
'01:03:59 PM'
$ LC_TIME=de_DE.UTF-8 python3
>>> import locale
>>> import time
>>> locale.setlocale(locale.LC_TIME, locale.getdefaultlocale(('LC_TIME',)))
'de_DE.UTF-8'
>>> time.strftime("%p")
''
>>> time.strftime("%X")
'13:06:13'