正所谓当局者迷,今天当我遇到同样的代码,不同的环境(shell执行和pycharm执行)居然有不同的执行结果时,我百思不得其姐(嘿嘿)。
代码片段是关于 strptime 的:
其实呢,strptime或者strftime格式化参数里有一些是跟locale相关的,比如这里的 %a %b 等,所以在不对的 locale 环境下,格式化出现了错误。
可以参考下面的示例:
Python 2.7.10 (default, Oct 23 2015, 19:19:21) [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import time >>> time.strptime('Thu, 24 Nov 2016 07:01:59 GMT', '%a, %d %b %Y %H:%M:%S GMT') time.struct_time(tm_year=2016, tm_mon=11, tm_mday=24, tm_hour=7, tm_min=1, tm_sec=59, tm_wday=3, tm_yday=329, tm_isdst=-1) >>> import locale >>> locale.setlocale(locale.LC_ALL, '') 'zh_CN.UTF-8' >>> time.strptime('Thu, 24 Nov 2016 07:01:59 GMT', '%a, %d %b %Y %H:%M:%S GMT') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 467, in _strptime_time return _strptime(data_string, format)[0] File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 325, in _strptime (data_string, format)) ValueError: time data 'Thu, 24 Nov 2016 07:01:59 GMT' does not match format '%a, %d %b %Y %H:%M:%S GMT' >>> time.strptime('2016 07:01:59', '%Y %H:%M:%S') time.struct_time(tm_year=2016, tm_mon=1, tm_mday=1, tm_hour=7, tm_min=1, tm_sec=59, tm_wday=4, tm_yday=1, tm_isdst=-1) >>> 阿里云oss sdk 使用遇到的问题用阿里云oss-python-SDK上传文件时,当我本地locale设置成 zh_CN.UTF-8 时,就回一直出问题,原因就在于上述的 strptime, 阿里云sdk代码片段如下:
def to_unixtime(time_string, format_string): with _STRPTIME_LOCK: return int(calendar.timegm(time.strptime(time_string, format_string)))然而从oss服务器上获得的timestring是这样的: Thu, 24 Nov 2016 07:01:59 GMT, 所以在我的环境里做格式化就会出错,所以我对代码做了如下修改:
def to_unixtime(time_string, format_string): with _STRPTIME_LOCK: time_locale = locale.setlocale(locale.LC_TIME) if time_locale.find('en') != 0 and time_locale != 'C': locale.setlocale(locale.LC_TIME, 'en_US') unixtime = int(calendar.timegm(time.strptime(time_string, format_string))) locale.setlocale(locale.LC_TIME, time_locale) else: unixtime = int(calendar.timegm(time.strptime(time_string, format_string))) return unixtime在调用 strptime 这个方法前增加了兼容,先检查locale,如果不是英文类型并且不是默认的"C"类型时,将 LC_TIME 切换成英文,执行完 strptime 后再还原回来。