python 3.4 vs. 3.5 strftime相同的locale不同的输出

时间:2016-06-07 19:44:16

标签: python datetime

在python 3.4.x(Windows 10 Home)中执行这些命令

import locale
from datetime import datetime
locale.setlocale(locale.LC_ALL, 'Spanish')
datetime.strftime(datetime.now(), '%a %d %b %Y')

渲染输出

'Spanish_Spain.1252'
'mar 07 jun 2016'

但是使用Python 3.5.x,输出是

'Spanish_Spain.1252'
'ma. 07 jun. 2016'

我无法找到有关此更改的任何内容。

1 个答案:

答案 0 :(得分:1)

好的,我向Python bug跟踪器发出了问题,Eryk Sun回答了我的问题:

  

3.5+使用的通用CRT使用Windows实现语言环境   区域设置名称[1],在Vista中引入。西班牙语的例子   包括',' es-ES'和' es-ES_tradnl' 。后者是   西班牙的传统排序,有3个字母的缩写   一周的日子。西班牙的默认值是现代排序   使用2个字母的缩写。

     

旧的LCID系统[2]默认为传统的排序(0x40A),to   哪个旧的CRT映射不合格"西班牙语"。现代排序(0xC0A)   有"西班牙语 - 现代" [3]。通用CRT仍然是荣誉   "西班牙语现代" [4],但只是"西班牙语"相反,它本身被映射   中立" es",使用现代排序。

     

如果您需要在两个版本中使用传统形式,那么在3.4中   它只是"西班牙语",但3.5+需要具有排序的区域设置名称   后缀。我实际上无法在MSDN上找到列出该表的表   " tradnl"排序名称附加到" es-ES",所以我写了一个快速脚本   找到它,假设至少" tra"将在名称中:

import re
import ctypes

kernel32 = ctypes.WinDLL('kernel32')

LOCALE_ENUMPROCEX = ctypes.WINFUNCTYPE(
    ctypes.c_int,
    ctypes.c_wchar_p,
    ctypes.c_uint,
    ctypes.c_void_p)

def find_locale(pattern):
    result = []
    @LOCALE_ENUMPROCEX
    def cb(locale, flags, param):
        if re.match(pattern, locale, re.I):
            result.append(locale)
        return True
    kernel32.EnumSystemLocalesEx(cb, 0, None, None)
    result.sort()
    return result

>>> find_locale('es-.*TRA.*')
['es-ES_tradnl']

>>> import locale, time
>>> locale.setlocale(locale.LC_TIME, 'es-ES_tradnl')
'es-ES_tradnl'
>>> time.strftime('%a')
'mié'
     

请注意,西班牙语中的缩写通常以句点结尾。它' S   出现在除西班牙以外的每个国家,如墨西哥:

>>> locale.setlocale(locale.LC_TIME, 'spanish_mexico')
'Spanish_Mexico.1252'
>>> time.strftime('%a')
'mié.'
     

或使用区域设置名称(3.5 +):

>>> locale.setlocale(locale.LC_TIME, 'es-MX')
'es-MX'
>>> time.strftime('%a')
'mié.'
     

请注意,Python仍然不支持解析语言环境名称:

>>> locale.getlocale(locale.LC_TIME)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python35\lib\locale.py", line 578, in getlocale
    return _parse_localename(localename)
  File "C:\Program Files\Python35\lib\locale.py", line 487, in _parse_localename
    raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: es-MX
     

由于区域设置名称不包含编码,因此需要对其进行解析   getlocale()将需要额外的调用来获取语言环境的ANSI   代码页,以防有人想要更新语言环境模块以支持   这样:

>>> LOCALE_IDEFAULTANSICODEPAGE = 0x1004
>>> buf = (ctypes.c_wchar * 10)()
>>> kernel32.GetLocaleInfoEx('es-MX', LOCALE_IDEFAULTANSICODEPAGE, buf, 10)
5
>>> buf.value
'1252'
     

如果此处没有其他人担心,我将此问题作为第3个问题解决   派对在一天左右。语言环境中的不一致是西班牙语#34;   映射到不同版本的CRT完全是微软的   问题

     

[1]:https://msdn.microsoft.com/en-us/library/dd373814 [2]:   https://msdn.microsoft.com/en-us/library/dd318693 [3]:   https://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.100%29.aspx   [4]:https://msdn.microsoft.com/en-us/library/39cwe7zf.aspx

http://bugs.python.org/msg267835