Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python3 datetime.datetime.strftime failed to accept utf-8 string format

python3 datetime.datetime.strftime failed to accept utf-8 string format

what I did is::

# encoding: utf-8
import datetime

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

and what I get is:

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

Why and how can I fix this?

like image 793
truease.com Avatar asked Apr 16 '13 09:04

truease.com


3 Answers

The problem is not in datetime, it's in print. See PrintFails

Ah, it's not exactly that - although it has the same cause, and you're likely to have that problem writing Unicode to stdout. (Using an IDE with a Python shell eg an up-to-date IDLE, avoids this.)

The strftime() function which is what datetime.strftime() ends up calling, is part of the C standard library, which under Windows/MSVCRT can't deal with Unicode strings. (Although in theory you could work around it by setting code page to 65001 and using UTF-8, there are serious long-standing bugs in the C runtime for that code page.)

Workaround in Python could be to replace out the non-ASCII characters until after the call:

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

Or to eschew strftime and do it yourself.

This should probably be considered a bug in time.strftime() and fixed there, by either of these means. It would make sense to add a Python-native implementation of strftime - they have already had to do the same for strptime due to other platform bugs in that function.

like image 163
bobince Avatar answered Oct 09 '22 06:10

bobince


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

'2018年04月12日 15时55分32秒'
like image 4
liuzhijun Avatar answered Oct 09 '22 07:10

liuzhijun


my work around

# -*- 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)

the result is

D:\Projects\pytools>python a.py
2013-04-16 20:14:22.518358
%2013年04月16日 %
like image 1
truease.com Avatar answered Oct 09 '22 06:10

truease.com