解决 time.strptime(today.strftime("%x"), "%x") 在某些区域设置中失败的问题

发布于 2024-12-08 22:57:04 字数 2300 浏览 1 评论 0 原文

尝试在文本 GUI 小部件中显示本地化日期字符串。我目前采取的方法是将带有 datetime.datetime.strftime("%x") 的本地化字符串显示到文本小部件中,以便用户可以编辑它。然后我尝试用 time.strptime("x") 解析字符串。

当前的问题是,对于某些语言环境(or_IN、ja_JP.UTF-8、ko_KO.UTF-8),time.strptime("x") 无法解析 datetime.datetime.strftime("%x") 生成的格式。 它总是抛出一个 ValueError 尝试解析它。

我怀疑这是在日期格式中使用双字节分隔符的 strptime 和日期字符串的问题。这也可能是一个问题,%x 对于 strftime 和 strptime 意味着什么(如果我理解正确的话,一个基本上只是 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

Trying to display a localized date string in a text gui widget. The approach I am taking at the moment is to display the localized string with datetime.datetime.strftime("%x") into a text widget, so that a user can edit it. Then I try to parse the string with time.strptime("x").

The current problem is that for some locales (or_IN, ja_JP.UTF-8, ko_KO.UTF-8) time.strptime("x") can't parse the format generated by datetime.datetime.strftime("%x").
It always throws a ValueError trying to parse this.

I suspect this is a problem with strptime and date strings that use doublebyte seperators in the date format. It could also be an issue with differences in what %x means for strftime and strptime (if I understand correctly, one is basically just the glibc implementation, while the other is python specific).

I'm looking for a better approach to handling localized date strings, so that they can be edited in the ui.

#!/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

And a sample output of this test program on my system (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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月下伊人醉 2024-12-15 22:57:07

检查 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']
>>>

Check whether you have your locales in locale_alias dictionary

>>> 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']
>>>
朱染 2024-12-15 22:57:07

使用工具包的日期小部件而不是文本小部件。所有主要工具包都有一个可以正常工作的日期小部件,并且比具有任何日期表示形式的文本字段更容易编辑。

Use your toolkit's date widget instead of a text widget. All major toolkits have a date widget that just works, and is much easier to edit than a textfield with whatever date representation.

梦幻之岛 2024-12-15 22:57:07

最终,只是将日期的文本条目更改为使用 iso 日期格式,ala:
2013年12月31日。这在原本可爱的本地化用户界面中有点不和谐,但可惜。

在这种特殊情况下,本机工具包没有提供基于文本的日期
条目和使用场景使得搜索遥远的未来日期变得很常见
(意味着在 GUI 日历小部件中点击数十次)。

这个问题的其他类似变体也导致了这种变化。对于一些区域设置,
特别是使用日期格式且月份标题会发生变化的区域设置
一个字形到两个字符的名称,内置的 python strptime 会失败,即使
具有正确的区域设置以及其他格式正确的字符串。为了奖金
恶化,在某些地区,只有当月份> 时才会失败。 10、这样就可以了
十一月/十二月除外的工作。对于其他语言环境,这是 glibc strptime
失败。上游存在这两种情况的已提交错误。

Eventually, just changed the text entry for the date to use iso date format, ala:
2013-12-31. It's a little jarring in a otherwise lovely localized ui, but alas.

In this particular case, the native toolkit did not provide a text based date
entry, and usage scenario makes searching on dates far in the future common
(meaning dozens of clicks in the gui calendar widget).

Other similar variations of this problem also led to that change. For a few locales,
particularly locales that used a date format with month titles that would change from
a single glyph to a two char name, the built in python strptime would fail, even
with the correct locale, and an otherwise correctly formatted strings. For bonus
aggravation, in some locales, it would only fail if the month > 10, so it would
work except for nov/dec. For other locales, it was the glibc strptime that would
fail. Filed bugs for both cases exist upstream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文