python3 datetime.datetime.strftime无法接受utf-8字符串格式

时间:2013-04-16 09:59:27

标签: python unicode python-3.x

python3 datetime.datetime.strftime未能接受utf-8字符串格式

我做的是::

# encoding: utf-8
import datetime

f = "%Y年%m月%d日"
now = datetime.datetime.now()
print( now.strftime(f) )

我得到的是:

D:\pytools>python a.py
Traceback (most recent call last):
  File "a.py", line 6, in <module>
    print( now.strftime(f) )
UnicodeEncodeError: 'locale' codec can't encode character '\u5e74' in position 2
: Illegal byte sequence

为什么以及如何解决此问题?

5 个答案:

答案 0 :(得分:6)

问题不在datetime,而在print。见PrintFails

啊,这不完全是 - 尽管它有相同的原因,并且你很可能将这个问题写入stdout。 (使用带有Python shell的IDE,例如最新的IDLE,可以避免这种情况。)

strftime()最终调用的datetime.strftime()函数是C标准库的一部分,它在Windows / MSVCRT下无法处理Unicode字符串。 (虽然理论上你可以通过将代码页设置为65001并使用UTF-8来解决它,但是在该代码页的C运行时中存在严重的长期错误。)

Python中的解决方法可能是在调用之后替换非ASCII字符:

strftime('%Y{0}%m{1}%d{2}').format(*'年月日')

或者回避strftime并自己动手。

这应该被认为是time.strftime()中的一个错误,并通过这些方法中的任何一种来修复。添加strftime的Python原生实现是有意义的 - 由于该函数中的其他平台错误,它们已经必须对strptime执行相同的操作。

答案 1 :(得分:1)

我的工作

# -*- coding: utf-8 -*-
import datetime

now = datetime.datetime.now()
print( now )



import re

def strftime(datetimeobject, formatstring):
    formatstring = formatstring.replace("%%", "guest_u_never_use_20130416")
    ps = list(set(re.findall("(%.)", formatstring)))
    format2 = "|".join(ps)
    vs = datetimeobject.strftime(format2).split("|")
    for p, v in zip(ps, vs):
        formatstring = formatstring.replace(p, v)
    return formatstring.replace("guest_u_never_use_20130416", "%")

r = strftime(now, "%%%Y年%m月%d日 %%")
print(r)

结果是

D:\Projects\pytools>python a.py
2013-04-16 20:14:22.518358
%2013年04月16日 %

答案 2 :(得分:1)

>>> now.strftime('%Y年%m月%d日 %H时%M分%S秒'.encode('unicode- 
 escape').decode()).encode().decode("unicode-escape")

'2018年04月12日 15时55分32秒'

答案 3 :(得分:0)

我在windows10上也有同样的问题,修复它:

import locale
locale.setlocale(locale.LC_CTYPE, 'chinese')
print(datetime.now().strftime('%Y年%m月%d日 %H时%M分%S秒'))

结果:2017年04月01日15时56分34秒

答案 4 :(得分:0)

它对我有用,见下文:

import datetime
from contextlib import contextmanager
import locale


@contextmanager
def locale_block(local_name: str, lc_var=locale.LC_ALL):
    org_local = locale.getlocale()
    try:
        yield locale.setlocale(lc_var, local_name)
    finally:
        locale.setlocale(lc_var, org_local)


with locale_block('zh'):
    print(datetime.datetime.now().strftime('%Y年%m月%d日'))

它将在离开with语句后恢复语言环境的值。