【已解决】python 3.7 进行字符串转时间时报raise ValueError(‘unknown locale: %s‘ % localename)

python 3.7 进行字符串转时间时报 ValueError('unknown locale: %s' % localename)

报错信息:

    self.all_list = self.init_data("")
  File "F:/pycharmProject/auto/download_new.py", line 440, in init_data
    print(time.strptime(str,"%Y-%m-%d %H:%M:%S"))
  File "C:\Python37\lib\_strptime.py", line 277, in <module>
    _TimeRE_cache = TimeRE()
  File "C:\Python37\lib\_strptime.py", line 191, in __init__
    self.locale_time = LocaleTime()
  File "C:\Python37\lib\_strptime.py", line 69, in __init__
    self.lang = _getlang()
  File "C:\Python37\lib\_strptime.py", line 28, in _getlang
    return locale.getlocale(locale.LC_TIME)
  File "C:\Python37\lib\locale.py", line 591, in getlocale
    return _parse_localename(localename)
  File "C:\Python37\lib\locale.py", line 499, in _parse_localename
    raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: zh-CN

datetime.strptime 、time.strptime 都报同样的错误

time.strptime(‘2020-08-11 10:08:02’,’%Y-%m-%dT%H:%M:%S’)

datetime.strptime(‘2020-08-11 10:08:02’,’%Y-%m-%dT%H:%M:%S’),此时报下面错误:
raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: zh-CN

而命令行直接通过main方法run时则无问题。

意思是没有找到locale 的值(或者是没有找到),查了多个方法都是要设置环境变量,但是这个方法不好,

最后,查看了一下local.py的源码及说明:

def _parse_localename(localename):

    """ Parses the locale code for localename and returns the
        result as tuple (language code, encoding).

        The localename is normalized and passed through the localealias engine. 
        A ValueError is raised in case the locale name cannot be parsed.

        The language code corresponds to RFC 1766.  
         code and encoding can be None in case the values cannot be determined or are unknown to this implementation.
注释翻译:

解析localename的区域设置代码并返回结果为tuple (language code, encoding)  即元组(语言代码、编码)。
localename是规范化的,并通过locale alias引擎传递。

如果无法解析语言环境名称,将引发ValueError。
该语言代码对应于RFC 1766。

代码(language code)和编码(encoding)在无法确定值或此实现未知的情况下,可以为None

"""

code = normalize(localename) #这个方法在下面列出来了,用来查找对应的code的
if '@' in code:
    # Deal with locale modifiers
    code, modifier = code.split('@', 1)
    if modifier == 'euro' and '.' not in code:
        # Assume Latin-9 for @euro locales. This is bogus,
        # since some systems may use other encodings for these
        # locales. Also, we ignore other modifiers.
        return code, 'iso-8859-15'

if '.' in code:
    return tuple(code.split('.')[:2])
elif code == 'C':
    return None, None
elif code == 'UTF-8':
    # On macOS "LC_CTYPE=UTF-8" is a valid locale setting
    # for getting UTF-8 handling for text.
    return None, 'UTF-8'
raise ValueError('unknown locale: %s' % localename) #这个就是报错抛出的异常
def normalize(localename):

    """ Returns a normalized locale code for the given locale
        name.

        The returned locale code is formatted for use with
        setlocale().

        If normalization fails, the original name is returned
        unchanged.

        If the given encoding is not known, the function defaults to
        the default encoding for the locale code just like setlocale()
        does.

    """
    # Normalize the locale name and extract the encoding and modifier
    code = localename.lower()
    if ':' in code:
        # ':' is sometimes used as encoding delimiter.
        code = code.replace(':', '.')
    if '@' in code:
        code, modifier = code.split('@', 1)
    else:
        modifier = ''
    if '.' in code:
        langname, encoding = code.split('.')[:2]
    else:
        langname = code
        encoding = ''

    # First lookup: fullname (possibly with encoding and modifier)
    lang_enc = langname
    if encoding:
        norm_encoding = encoding.replace('-', '')
        norm_encoding = norm_encoding.replace('_', '')
        lang_enc += '.' + norm_encoding
    lookup_name = lang_enc
    if modifier:
        lookup_name += '@' + modifier
    code = locale_alias.get(lookup_name, None)
    if code is not None:
        return code
    #print('first lookup failed')

打断点,一步一步往调用的方法里面追,发现调用了local.py中的_parse_localname()方法调用了normalize(localename)方法 ,

local.py中定义的有个字典:locale_alias,里面有个zh_cn(注意连接符是下划线)的key,为进行locale设置时,传入的是zh-cn(注意中间是减号) ,所以匹配不到,抛出异常,根据上面的注释说明,可以把locale的LC_ALL(所有地域属性)设置为空(None)让程序使用默认,不会抛出异常

看完后知道原来是,

解决方法:
在调用strptime前先设置locale:

import locale
import datetime.datetime
locale.setlocale(locale.LC_ALL, '')
datetime.strptime('2020-08-11 10:08:02','%Y-%m-%dT%H:%M:%S')
import locale
import time
#执行strptime之前先设置local.LC_ALL,设置为空,默认从系统取
locale.setlocale(locale.LC_ALL, '')
time.strptime('2020-08-11 10:08:02','%Y-%m-%dT%H:%M:%S')

此时便能正常转换了。
locale.setlocale(locale.LC_ALL, '')中第二个参数为空时,表示将locale设置为系统默认,设置完成后的local值:

print(locale.getdefaultlocale()) 结果--> ('zh_CN', 'cp936')
print(locale.getlocale()) 结果--> ('Chinese (Simplified)_China', '936')

终于解决了。

stackoverflow也有其他的解决方法

https://stackoverflow.com/questions/47910688/getting-the-current-locale-on-windows

猜你喜欢

转载自blog.csdn.net/yy4545/article/details/107928830