Python和macOS上意外的strftime()行为
我获得了与datetime.strftime()输出不一致的行为 我正在使用macOS Sierra 10.12.6和Python 3.6.2。我有一个Python程序,名为Python和macOS上意外的strftime()行为,python,python-3.x,macos-sierra,strftime,Python,Python 3.x,Macos Sierra,Strftime,我获得了与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
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
其中日期和时间以另一个区域设置写入。这是怎么发生的?这是一个bug还是有任何原因导致这种行为
我感到困惑,因为Python文档提到
%c
指的是“区域设置的适当日期和时间表示法”,所以我认为系统的区域设置是“适当的”区域设置;)(请参阅,第8.1.8节)python结果正确,strftime('%c')返回相同的结果格式。python结果正确,strftime('%c')返回相同的结果格式。深入研究区域设置
模块,我在getdefaultlocale()
的描述中发现:
根据POSIX,一个没有调用
setlocale(LC_ALL,“”)使用可移植的“C”语言环境运行。
调用setlocale(LC_ALL,“”)可以将默认区域设置用作
由LANG变量定义。既然我们不想干涉
因此,通过当前的区域设置,我们可以模拟该行为
以上述方式
由此看来,打电话是一种很好的做法
locale.setlocale(locale.LC_ALL, '')
将您的区域设置设置为希望从调用方环境继承的区域设置。这样做,您将从strftime
获得预期的输出
也就是说,在macOS 10.12安装中,我注意到Python2.7和Python3.6的行为有所不同。启动时,
locale.getdefaultlocale()
和locale.getlocale()
都返回Python 3中的('en_US','UTF-8')
。但是,在Python 2中,getlocale()
返回(无,无)
,直到调用setlocale
。在这两种情况下,strftime
仍然需要调用setlocale
,才能实际使用设置的区域设置,而不是默认的C
locale。我不知道这是否代表一个bug,或者如果是的话,哪一个是bug实例。深入了解一下区域设置
模块,我在getdefaultlocale()
的描述中发现了这一点:
根据POSIX,一个没有调用
setlocale(LC_ALL,“”)使用可移植的“C”语言环境运行。
调用setlocale(LC_ALL,“”)可以将默认区域设置用作
由LANG变量定义。既然我们不想干涉
因此,通过当前的区域设置,我们可以模拟该行为
以上述方式
由此看来,打电话是一种很好的做法
locale.setlocale(locale.LC_ALL, '')
将您的区域设置设置为希望从调用方环境继承的区域设置。这样做,您将从strftime
获得预期的输出
也就是说,在macOS 10.12安装中,我注意到Python2.7和Python3.6的行为有所不同。启动时,
locale.getdefaultlocale()
和locale.getlocale()
都返回Python 3中的('en_US','UTF-8')
。但是,在Python 2中,getlocale()
返回(无,无)
,直到调用setlocale
。在这两种情况下,strftime
仍然需要调用setlocale
,才能实际使用设置的区域设置,而不是默认的C
locale。我不知道这是否代表一个bug,或者如果是的话,哪一个是bug实例。有许多不同的区域设置类别,它们都是独立配置的,并且locale.getlocale()
只为您设置LC\u CTYPE
类别。时间格式由LC\u-Time
类别控制,您可以使用locale.getlocale(locale.LC\u-Time)
检查该类别
您可以使用
locale.setlocale(locale.LC_ALL')
将所有区域设置类别的设置设置设置为用户的默认设置(通常在LANG
环境变量中指定)setlocale
不是线程安全的,因此这通常在程序开始时进行。有许多不同的区域设置类别,它们都是独立配置的,locale.getlocale()
只为您设置LC\u CTYPE
类别。时间格式由LC\u-Time
类别控制,您可以使用locale.getlocale(locale.LC\u-Time)
检查该类别
您可以使用
locale.setlocale(locale.LC_ALL')
将所有区域设置类别的设置设置设置为用户的默认设置(通常在LANG
环境变量中指定)setlocale
不是线程安全的,所以这通常在程序开始时进行。我知道这并不能回答问题,但你说你在使用python3,但你的shebang调用了Python2。。。应该是#/usr/bin/python3你能看到它给了你什么吗?我认为Python最终会委托Cstrftime
来处理这个问题。@AllenMoh谢谢,你说得对,我已经修复了它。无论如何,在上面的示例中,它应该不会改变任何内容。如果您“显式”将语言环境设置为使用系统语言环境,并将其与locale.setlocale(locale.LC_ALL')
,您将获得预期的意式输出。我不知道为什么这看起来是必要的。@user2357112我怎么能看到C函数给了我什么man strftime
只是说%c被时间和日期的国家表示形式所取代。
并且strftime()函数使用当前的语言环境
我知道这并不能回答问题,但是你说你在使用python3,但是你的shebang调用了python2。。。应该是#/usr/bin/python3你能看到它给了你什么吗?我认为Python最终会委托Cstrftime
来处理这个问题。@AllenMoh谢谢,你说得对,我已经修复了它。无论如何,它是