Issues : Windows + Korean + time.strftime()

In [1]:
from datetime import datetime, date, time

datetime.now().strftime('%Y년 %-d월 %-m일')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-1-efd39827dcf5> in <module>()
      1 from datetime import datetime, date, time
      2 
----> 3 datetime.now().strftime('%Y년 %-d월 %-m일')

UnicodeEncodeError: 'locale' codec can't encode character '\ub144' in position 2: Illegal byte sequence

위의 코드는 linux/macOS에서는 잘 작동하지만 windows에서는 UnicodeEncodeErrorInvalid format string 오류가 발생할 수 있습니다.

python의 datetime 패키지가 libc 기반으로 짜여서 각 시스템에 의존적이기 때문에 발생하는 문제입니다.

인코딩 문제를 해결하더라도 windows에서 사용할 수 있는 formatting code(ex. %Y, %H) 또한 한정되어 있다는 점을 유의하세요.

예를 들어 수업시간에 소개된 '%-d'(날짜 1-31 코드) 또한 windows에서 문제가 발생하기도 합니다.

(윈도에서 사용 가능한 formatting code 리스트 참고: https://msdn.microsoft.com/en-us/library/fe06s4ak.aspx, https://docs.python.org/3/library/time.html )

아래에는 간단한 해결 방법들을 소개합니다.

1. strftime formatting code 속에 한글을 사용하지 않는다

strftime과 string 자료형의 format 함수를 함께 사용하여 문제를 해결할 수 있습니다. (case 1)

혹은 아예 strftime을 사용하지 않고 format 함수 등을 이용하여 유사하거나 더 다양한 문자열을 만들 수 있습니다 (case 2,3)

(format 참고 : [https://pyformat.info/])

In [2]:
now=datetime.now()

# case 1
print(now.strftime('%Y{0} %m{1} %d{2}').format(*'년월일'))

# case 2
print(f'{now.year}{now.month}{now.day}일')

# case 3
print('{}{}{}일'.format(now.year, now.month, now.day))
2018년 09월 20일
2018년 9월 20일
2018년 9월 20일

2. 인코딩을 강제로 변경한다

종종 사용되는 한 줄 짜리 해결책입니다.

In [3]:
today2 = datetime.now().strftime("%Y년 %m월 %d일".encode('unicode-escape').decode()).encode().decode('unicode-escape')

print(today2)
2018년 09월 20일

3. 시스템 locale을 변경한다

전체 python 프로그램의 다른 부분에 영향을 줄 수 있다는 단점이 있지만 locale을 변경하면 strftime 함수에서도 한글 문자열을 해석할 수 있습니다

In [4]:
import locale
locale.setlocale(locale.LC_CTYPE, 'korean')

today3 = datetime.now().strftime("%Y년 %m월 %d일")

print(today3)
2018년 09월 20일