1

我想创建一个“unicode 三明治”,其中包含一些日期/时间值并且与语言环境无关。对于初学者来说,unicode 三明治一词描述了从字节转换为 unicode 并返回到程序边界的做法,即外部的字节和内部的 unicode。

今天早上我观看了Ned Batchelder 关于 unicode 的精彩视频,并试图将我的一些代码转换为符合他的明智建议。

我遇到的问题是我无法确定如何确定由返回的字符串str(date)或其等价物的编码。我的想法是做这样的事情,为了清楚起见有点冗长:

date_str_encoding = some_magical_method_I_have_yet_to_discover()
date = datetime.datetime(2013, 10, 16).date()
date_str = date.strftime('%A %B %d, &Y')  # perhaps 'Sábado Octubre 19, 2013'
date_unicode = date_str.decode(date_str_encoding)

Ned 的 unicode “生活事实”之一是“你无法推断字节的编码。你必须被告知,否则你必须猜测。” 不幸的是,我在 Python 文档中找不到日期时间的特定细节。

另一个 SO 帖子提到了 locale.getlocale() 的使用,但对我来说返回 (None, None)。

如何在运行时可靠地发现 Python 日期字符串的编码?

4

2 回答 2

4

在 CPython 2.7 中,datetime.date.strftime是. 原则上,这取决于. 因此,您正在寻找的是:time.strftimestrftime(3)LC_TIME

import locale
def date_format_encoding():
    return locale.getlocale(locale.LC_TIME)[1] or locale.getpreferredencoding()

datetime.date.__str__以下是问题编辑之前相关的解构。

在 CPython 2.7 中,datetime.date.__str__是用 C 实现的,它是:

static PyObject *
date_str(PyDateTime_Date *self)
{
    return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
}

datetime.date.isoformatis 反过来在 C 中实现为:

static char *
isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
{
    int x;
    x = PyOS_snprintf(buffer, bufflen,
                      "%04d-%02d-%02d",
                      GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
    assert(bufflen >= x);
    return buffer + x;
}

基本上,从来没有这样的情况,其中返回的字节str(datetime.date)除了数字和“-”的 ascii 代码之外的任何内容。:_

str(my_date).decode('ascii')
于 2013-10-16T20:41:27.680 回答
2

为什么不date_str完全跳过?构造unicode函数接受日期对象。

>>> date_unicode = unicode(date)
>>> date_unicode
u'2013-10-16'

在内部,这调用str(date). 然后它解码这些字节。所以它相当于显式创建字节然后解码它们,但在我看来更清晰易读。并且值得养成使用unicode而不是显式使用的习惯strdecode因为某些对象将定义一个__unicode__可以返回规范 Unicode 表示的方法,而无需经过__str__。日期没有。

文档说:

对于日期 d,str(d) 等价于 d.isoformat()。

其定义为:

返回一个以 ISO 8601 格式表示日期的字符串,'YYYY-MM-DD'。例如,date(2002, 12, 4).isoformat() == '2002-12-04'。

所以那也将是ASCII。如果您的默认编码无法解码 ASCII,您就必须学习如何处理这种情况。

于 2013-10-16T20:16:34.347 回答