LoginSignup
22
25

More than 5 years have passed since last update.

PythonでUTC時刻をISO形式の文字列で受け取ってJSTのdatetimeに変換する

Last updated at Posted at 2019-03-10

ISO形式の時刻

年月日と時間の間にTが入っている日時の表現規格。
末尾にはTimezoneの情報も保持する規格です。

ISO 8601 - Wikipedia

基本形式、拡張形式があったり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

変換方法

以下、手順で変換します。

  1. dateutil.parser.parsedatetime に変換
  2. 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の表現の幅のなかで、いろんな入力値で結果を確認します。

iso_utc_to_jst.py
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

ただし、拡張形式の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の表現の幅のなかで、いろいろな入力値で結果を確認します。

iso_utc_to_jst2.py
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'",)
22
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
25