Pythonで文字列を時刻に変換する方法です
時刻を表す文字列
時刻を表す文字列にはいくつかのフォーマット(書式)があります
ISO8601の例
- 2020-06-14T13:04:46+09:00
RFC 3339の例
- 2020-06-14T04:04:46.000Z
- 2020-06-14T04:04:46.000000Z
これらは全部同じ時刻を表しています.
末尾の"Z"や"+09:00"はタイムゾーンを表しています.
Zは“Zulu time”で +00:00,UTCと同じ意味です.+09:00は日本のタイムゾーン(JST)です.
文字列からDatetimeへの変換
ISO8601とRFC3339の書式は似ているようで,微妙に違いがあります.
両者を混在させて pythonで扱う場合には注意が必要です.
ISO8601の場合
Python 3.7以降なら datetime.datetime.fromisoformat() を使うだけで変換できます
import datetime s = "2020-06-14T13:04:46+09:00" print ( datetime.datetime.fromisoformat(s) )
RFC3339 の場合
文字列の末尾が"Z"の場合 datetime.datetime.fromisoformat() は, ValueErrorの例外を出します.
ValueErrorの例外の例
ValueError: Invalid isoformat string: '2020-06-14T13:04:46+09:00Z'
この場合は "Z"を無視すれば Datetimeに変換できます
import datetime s = "2020-06-14T04:04:46.000Z" print ( datetime.datetime.fromisoformat(s[:-1]) )
重要な点が2つあります
1点目. "Z"は +00:00 なので,
- "2020-06-14T04:04:46.000Z"
- "2020-06-14T04:04:46.000"
- "2020-06-14T04:04:46.000+00:00"
は全部同じ時刻になります
2点目.
- 2020-06-14T13:04:46+09:00
- 2020-06-14T04:04:46.000Z
は同じ時刻です
タイムゾーンを補正しようとして
"2020-06-14T04:04:46.000+00:00"に9時間を足してしまうと
"2020-06-14T13:04:46.000+00:00"になります
これはJSTでは "2020-06-14T22:04:46.000+09:00"になります.つまり間違いです.
このように間違って+09:00を加算してしまわないようにするのがポイントになります
RFC3339形式を ISO8601形式に変換する
RFC3339形式の文字列を,ISO8601形式に変換してみます
import datetime import tz s = "2020-06-14T04:04:46.000Z" t = datetime.datetime.fromisoformat(s[:-1]) # タイムゾーン JSTの情報を取得 JST = tz.gettz('JST') # datetimeオブジェクト t のタイムゾーンを変更 t = t.astimezone(JST) print ( t.isoformat() )
これで ISO8601形式で '2020-06-14T13:04:46+09:00' が表示されます