Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
24
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@yu-sa

strftime() と strptime() を使ってtzinfo付きdatetime <-> stringの変換をやってみた

環境

Python 2.7.10

参考資料

8.1. datetime — 基本的な日付型および時間型

strftimeを使ってtzinfoを保持したdatetime文字列を取得

>>> from datetime import datetime
>>> import pytz
>>> 
>>> jst = pytz.timezone('Japan')
>>> jst_datetime = datetime.now().replace(tzinfo=jst)
>>> print jst_datetime
2015-11-12 16:09:18.544266+09:00
>>> jst_datetime_str = datetime.strftime(jst_datetime, '%Y-%m-%d %H:%M:%S %z')
>>> print jst_datetime_str
2015-11-12 16:09:18 +0900
>>> datetime.strftime(jst_datetime, '%Y-%m-%d %H:%M:%S %Z')
'2015-11-12 16:09:18 JST'

tzinfo付きdatetime文字列を出力する事が出来る。

strptimeを使ってdatetime文字列からtzinfo付きdatetimeを取得

>>> print jst_datetime_str
2015-11-12 16:09:18 +0900
>>> datetime.strptime(jst_datetime_str, '%Y-%m-%d %H:%M:%S %z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'
>>> 

tzinfo付きdatetime文字列を使ってtimsezone付きdatetimeを取得しようとしたのだがエラー。

ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

'%z'指定子が悪いフォーマットだぞ的なエラーが発生する。

色々調べてみた結果
http://stackoverflow.com/questions/2609259/converting-string-to-datetime-object-in-python

python2.7では%zはサポートされていないよう。python3.2なら動くらしい。
バージョン変える事が出来ないので他の方法を試す

>>> jst_datetime_str = datetime.strftime(jst_datetime, '%Y-%m-%d %H:%M:%S %Z')
>>> print jst_datetime_str
2015-11-12 16:09:18 JST
>>> datetime.strptime(jst_datetime_str, '%Y-%m-%d %H:%M:%S %Z')
datetime.datetime(2015, 11, 12, 16, 9, 18)

%Zを使ってやってみたのだが、今度はエラーは発生しないもののtzinfoが付いてないdatetimeが出来てしまう。

他を探してみると
http://nekoya.github.io/blog/2013/06/21/python-datetime/

この人も、%Zを使ってだめだったので「replace(tzinfo=pytz.utc)」を使って設定しているようだ。
指定子を使用して変換するのはもう無理そうなので、ごり押しで対応してみた

>>> from datetime import datetime
>>> import pytz
>>> 
>>> jst = pytz.timezone('Japan')
>>> jst_datetime = datetime.now().replace(tzinfo=jst)
>>> print jst_datetime
2015-11-12 16:54:19.564920+09:00
>>> jst_datetime_str = datetime.strftime(jst_datetime, '%Y-%m-%d %H:%M:%S') + ' ' + jst_datetime.tzinfo.zone
>>> print jst_datetime_str
2015-11-12 16:54:19 Japan
>>> zone = jst_datetime_str.split(' ')[-1]
>>> print zone
Japan
>>> datetime_str = ' '.join(jst_datetime_str.split(' ')[:2])
>>> print datetime_str
2015-11-12 16:54:19
>>> datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.timezone(zone))
datetime.datetime(2015, 11, 12, 16, 54, 19, tzinfo=<DstTzInfo 'Japan' JST+9:00:00 STD>)

こんな感じ。

まとめ

・python2.7だとstrptimeで指定子 '%Z'と'%z'は使えない。
・ただ、strftimeでは正常に使える。
・後、確認はしてないがpython3.2だとstrptimeでも使えるようだ。
・正直相当無理矢理な感じだけど、他にいい方法ないのかな。

24
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
24
Help us understand the problem. What is going on with this article?