在某些地区,time.strptime(today.strftime("%x"), "%x") 失败的解决方法
我正在尝试在一个文本界面小部件中显示本地化的日期字符串。目前我采用的方法是使用datetime.datetime.strftime("%x")将本地化的字符串显示在文本小部件中,这样用户就可以编辑它。然后我尝试用time.strptime("x")来解析这个字符串。
现在的问题是,对于某些地区设置(比如印度、日语和韩语),time.strptime("x")无法解析datetime.datetime.strftime("%x")生成的格式。每次尝试解析时,它都会抛出一个ValueError错误。
我怀疑这是strptime和使用双字节分隔符的日期字符串之间的问题。也可能是因为strftime和strptime对%x的定义不同(如果我理解没错,一个是glibc的实现,另一个是Python特有的)。
我在寻找更好的方法来处理本地化的日期字符串,以便它们可以在用户界面中被编辑。
#!/usr/bin/python
# We are trying to present a localized date in a text widget, so
# that a user could potentially edit it, and then we try to
# parse it with datetime.strptime
# however, even if the user doesn't edit the date produced
# by today.strftime("%x"), time.strptime(DATE, "%x") fails
# to parse it
# Not sure what's going on there before. I've seen this once
# before with in_OR, and that turned out to be a locale bug
# in glibc. This could also be the case, so what I'm looking
# for is a more robust approach to this problem that will
# work on all locales
# platform: fedora 14, x86_64
# Python 2.7 (r27:82500, Sep 16 2010, 18:02:00)
# [GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2
import datetime
import time
import locale
today = datetime.date.today()
# works for "C"
locale.setlocale(locale.LC_ALL, 'C')
print time.strptime(today.strftime("%x"), "%x")
# works for en_us.utf8
locale.setlocale(locale.LC_ALL, 'en_US.utf8')
print time.strptime(today.strftime("%x"), "%x")
# fails for 'ja_JP.UTF-8'
loc = 'ja_JP.UTF-8'
locale.setlocale(locale.LC_ALL,loc)
try:
print today.strftime("%x")
print time.strptime(today.strftime("%x"), "%x")
except ValueError:
print "failed for %s" % loc
loc = 'ko_KR.UTF-8'
locale.setlocale(locale.LC_ALL,loc)
try:
print today.strftime("%x")
print time.strptime(today.strftime("%x"), "%x")
except ValueError:
print "failed for %s" % loc
这是我在系统上运行这个测试程序的输出示例(fedora 14, x86_64):
time.struct_time(tm_year=2011, tm_mon=10, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=283, tm_isdst=-1)
time.struct_time(tm_year=2011, tm_mon=10, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=283, tm_isdst=-1)
2011年10月10日
failed for ja_JP.UTF-8
2011년 10월 10일
failed for ko_KR.UTF-8
3 个回答
最后,我把日期的输入格式改成了ISO日期格式,比如:2013-12-31。虽然在一个本来很美观的本地化界面中,这样的格式看起来有点突兀,但没办法。
在这个特定的情况下,原生工具包没有提供文本输入的日期选项,而使用场景中,查找很远未来的日期是很常见的(这意味着在图形界面的日历小部件上要点很多次)。
类似的问题也导致了这个改变。在一些地区,特别是那些使用月份名称的地方,月份的格式会从一个字母变成两个字母,这样的话,内置的Python strptime函数就会出错,即使使用了正确的地区设置,字符串格式也没问题。更麻烦的是,在某些地区,只有当月份大于10时才会出错,所以11月和12月就不行。对于其他地区,出错的是glibc的strptime。对于这两种情况,都已经在上游提交了bug报告。
用你工具包里的日期小部件,而不是文本小部件。所有主要的工具包都有一个日期小部件,它用起来很简单,比起用文本框输入各种日期格式要容易得多。
检查一下你的地区设置是否在 locale_alias 字典里。
>>> import locale
>>> len(locale.locale_alias)
843
>>> locale.locale_alias.keys()[:10]
['ko_kr.euc', 'is_is', 'ja_jp.mscode', 'kw_gb@euro', 'yi_us.cp1255', 'ca_es@euro', 'ja_jp.ujis', 'ar_ma', 'greek.iso88597', 'sr_yu.iso88592']
>>>