Python 和 macOS 上的意外 strftime() 行为

Unexpected strftime() behaviour on Python and macOS

我的行为与 datetime.strftime() 的输出不一致。

我使用的是 macOS Sierra 10.12.6 和 Python 3.6.2。我有一个 Python 程序,名为 wut.py,即

#!/usr/bin/python
from datetime import datetime
import locale
if __name__ == "__main__":
    print(locale.getlocale())
    print(datetime.today().strftime('%c'))

在终端中,我写

$ date
Gio 24 Ago 2017 18:54:01 CEST

这是意大利语的日期书写方式。那么

$ python3 ~/Desktop/wut.py 
('it_IT', 'UTF-8')
Thu Aug 24 18:54:03 2017

日期和时间是用另一个语言环境写的。这是怎么回事?这是错误还是这种行为有任何原因?

我很困惑,因为 Python 文档提到 %c 指的是 "Locale’s appropriate date and time representation.",所以我认为系统的语言环境是 "appropriate" ;) (参见 https://docs.python.org/3/library/datetime.html,第 8.1.8 节)

python 结果正确,strftime('%c') return 结果格式相同。

深入研究 locale 模块,我在 getdefaultlocale() 的描述下找到了这个:

According to POSIX, a program which has not called setlocale(LC_ALL, "") runs using the portable 'C' locale. Calling setlocale(LC_ALL, "") lets it use the default locale as defined by the LANG variable. Since we don't want to interfere with the current locale setting we thus emulate the behavior in the way described above.

据此,我认为调用

是个好习惯
locale.setlocale(locale.LC_ALL, '')

将您的语言环境设置为您希望从调用方环境继承的语言环境。这样做,您应该从 strftime.

获得预期的输出

也就是说,我注意到 Python 2.7 和 Python 3.6 在我的 macOS 10.12 安装上的行为有所不同。在启动时,locale.getdefaultlocale()locale.getlocale() 都 return ('en_US', 'UTF-8') 在 Python 3 中。但是在 Python 2 中,getlocale() returns (None, None) 直到我打电话给 setlocale。在任何一种情况下,strftime 仍然需要调用 setlocale 才能实际使用设置的语言环境,而不是默认的 C 语言环境。我不知道这是否代表一个错误,或者如果是,哪个是错误的实例。

有许多不同的语言环境类别,它们都是独立配置的,locale.getlocale() 只为您提供 LC_CTYPE 类别的设置。时间格式由 LC_TIME 类别控制,您可以使用 locale.getlocale(locale.LC_TIME).

进行检查

您可以使用 locale.setlocale(locale.LC_ALL, '') 将所有语言环境类别的设置设置为用户的默认设置(通常在 LANG 环境变量中指定)。 setlocale 不是线程安全的,因此这通常在程序开始时出现。