ISO形式の時刻
年月日と時間の間にTが入っている日時の表現規格。
末尾にはTimezoneの情報も保持する規格です。
基本形式、拡張形式があったりTimezoneの表現が複数あり、
ISO形式といっても同じ時間の表現に幅があります。
-
ISO形式の日時例
-
2019-03-08T22:34:56.123456+00:00
-
2019-03-08T22:34:56.123456+0000
-
2019-03-08T22:34:56.123456+00
-
2019-03-08T22:34:56.123456Z
-
20190308T223456Z
文字列の表現になるため、コードレベルで日時や日付として正確に扱うために、
このISO形式の 文字列 を datetime に変換します。
特に、コード上でJSTの日付や時間で扱いたい場合には、
UTCのISO形式の時刻を受け取ったら、datetimeに変換しJSTに変換します。
dateutil.parser がISOの表現の幅に対応していて優秀です。
UTC時刻をISO形式で受け取った時のJSTへの変換方法
準備
dateutil.parser を使うために必要なライブラリをpipで導入します。
pip install python-dateutil
変換方法
以下、手順で変換します。
- dateutil.parser.parse で datetime に変換
- datetime.astimezone でJSTに変換
import datetime
import dateutil.parser
str_timestamp = '2019-03-09T22:34:56.123456Z'
JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')
jst_timestamp = dateutil.parser.parse(str_date).astimezone(JST)
実行例
ISOの表現の幅のなかで、いろんな入力値で結果を確認します。
import datetime
import dateutil.parser
str_datetimes = ['2019-03-09T22:34:56.123456+00:00',
'2019-03-09T22:34:56.123456+0000',
'2019-03-09T22:34:56.123456+00',
'2019-03-09T22:34:56.123456Z',
'20190309T223456+00:00',
'20190309T223456Z']
JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')
for i, str_datetime in enumerate(str_datetimes):
try:
print('# ' + str(i+1))
print(' 入力値 :', str_datetime, type(str_datetime))
jst_datetime = dateutil.parser.parse(str_datetime).astimezone(JST)
print(' JST時刻:', jst_datetime, type(jst_datetime))
print(' JST日付:', jst_datetime.date(), type(jst_datetime.date()))
except Exception as e:
print(e.args)
すべて変換できます。
>python iso_utc_to_jst.py
# 1
入力値 : 2019-03-09T22:34:56.123456+00:00 <class 'str'>
JST時刻: 2019-03-10 07:34:56.123456+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
# 2
入力値 : 2019-03-09T22:34:56.123456+0000 <class 'str'>
JST時刻: 2019-03-10 07:34:56.123456+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
# 3
入力値 : 2019-03-09T22:34:56.123456+00 <class 'str'>
JST時刻: 2019-03-10 07:34:56.123456+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
# 4
入力値 : 2019-03-09T22:34:56.123456Z <class 'str'>
JST時刻: 2019-03-10 07:34:56.123456+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
# 5
入力値 : 20190309T223456+00:00 <class 'str'>
JST時刻: 2019-03-10 07:34:56+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
# 6
入力値 : 20190309T223456Z <class 'str'>
JST時刻: 2019-03-10 07:34:56+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-10 <class 'datetime.date'>
Python 3.7のfromisoformatの利用は注意
他の方法として、ISO形式の文字列をdatetimeに変換するfromisoformatという関数がバージョン3.7から追加されています。
[Python ドキュメント - datetime] (https://docs.python.org/ja/3/library/datetime.html)
ただし、拡張形式のISOで末尾のtimezoneの表現は+hh:mmしか対応できません。
変換方法
import datetime
str_timestamp = '2019-03-09T22:34:56.123456Z'
JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')
jst_datetime = datetime.fromisoformat(date_string).astime(JST)
実行例
ISOの表現の幅のなかで、いろいろな入力値で結果を確認します。
import datetime
str_datetimes = ['2019-03-08T22:34:56.123456+00:00',
'2019-03-08T22:34:56.123456+0000',
'2019-03-08T22:34:56.123456+00',
'2019-03-08T22:34:56.123456Z',
'20190308T223456+00:00',
'20190308T223456Z']
JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')
for i, str_datetime in enumerate(str_datetimes):
try:
print('# ' + str(i+1))
print(' 入力値 :', str_datetime, type(str_datetime))
jst_datetime = datetime.datetime.fromisoformat(str_datetime).astimezone(JST)
print(' JST時刻:', jst_datetime, type(jst_datetime))
print(' JST日付:', jst_datetime.date(), type(jst_datetime.date()))
except Exception as e:
print(e.args)
拡張形式のISOで末尾のtimezoneの表現は+hh:mmのみ変換できています。
>python iso_utc_to_jst2.py
# 1
入力値 : 2019-03-08T22:34:56.123456+00:00 <class 'str'>
JST時刻: 2019-03-09 07:34:56.123456+09:00 <class 'datetime.datetime'>
JST日付: 2019-03-09 <class 'datetime.date'>
# 2
入力値 : 2019-03-08T22:34:56.123456+0000 <class 'str'>
("Invalid isoformat string: '2019-03-08T22:34:56.123456+0000'",)
# 3
入力値 : 2019-03-08T22:34:56.123456+00 <class 'str'>
("Invalid isoformat string: '2019-03-08T22:34:56.123456+00'",)
# 4
入力値 : 2019-03-08T22:34:56.123456Z <class 'str'>
("Invalid isoformat string: '2019-03-08T22:34:56.123456Z'",)
# 5
入力値 : 20190308T223456+00:00 <class 'str'>
("Invalid isoformat string: '20190308T223456+00:00'",)
# 6
入力値 : 20190308T223456Z <class 'str'>
("Invalid isoformat string: '20190308T223456Z'",)