ISO8601 フォーマットの日付を読み取る方法

この記事では、時刻を表記する際の国際標準フォーマットである ISO8601 形式を Python で扱う方法について説明します。

ISO8601 に従う時刻表記については、Python に限った話ではありません。詳しくは別の記事 「ISO 8601 の時刻表記」をみてください。

最近では、海外との商取引が増えているところも多いのではないでしょうか。

グローバルな環境で使うコンピュータシステムを構築するにあたり、気をつけるポイントはいくつかありますが、 特に気をつけないといけないもののひとつは日付や時刻です。

例えばアメリカ国内だけで考えても、いくつもタイムゾーンがあるので、「何月何日何時」というだけでは情報として足りず、 タイムゾーンも含めて表記しないとあいまいさが残ってしまいます。

そのため、日付や時刻を表すのに統一した表記が必要となるわけで、その標準としてよく使われるのが ISO8601 フォーマット です。

日本時刻の 2018年1月1日午前10時30分なら、日本のタイムゾーンは UTC+9時間ですから、2018-01-01T10:30+0900 のように書きます。

省略形などその他の書き方もあります。

ここでは ISO8601 フォーマットの時刻を扱う例を紹介します。

環境設定

まずは環境設定です。ここでは pytz パッケージと iso8601 パッケージをインストールします。

テスト用の環境として、個別に環境を作るには virtualenv を利用すると他に影響を与えないので便利です。「Virtualenv の使い方」をみてください。

タイムゾーンを扱うのに pytz パッケージを使います。pip でインストールできます。

$ pip install pytz

同様に iso8601 パッケージをインストールするには、次のコマンドでインストールできます。

$ pip install iso8601

ISO8601 フォーマットの日付・時刻を読み取る

動作例は次の通りです。次のスクリプトを timestamp1.py として保存してください。

import pytz
import iso8601
from datetime import datetime

txt = '2010-04-01T09:00:00-07:00'
print('Original Text  : ' + txt)

# Parse Text
p = iso8601.parse_date(txt)
print('Parsed date    : ' + str(p))
print('UTC Offset     : ' + str(p.utcoffset()))

# UNIX Timestamp
ts = int(p.timestamp())
print('UNIX timestamp : ' + str(ts))

# ISO Format - UTC
utc_tz = pytz.timezone('UTC')
d = datetime.fromtimestamp(ts, utc_tz).isoformat()
print('ISO Format UTC : ' + d)

# ISO Format - LA
la_tz = pytz.timezone('America/Los_Angeles')
d = datetime.fromtimestamp(ts, la_tz).isoformat()
print('ISO Format LA  : ' + d)

ここでは Python3.6 を利用しています。

このスクリプトの実行結果は次のようになります。

$ python timestamp1.py
Original Text  : 2010-04-01T09:00:00-07:00
Parsed date    : 2010-04-01 09:00:00-07:00
UTC Offset     : -1 day, 17:00:00
UNIX timestamp : 1270137600
ISO Format UTC : 2010-04-01T16:00:00+00:00
ISO Format LA  : 2010-04-01T09:00:00-07:00

それぞれの出力内容について説明します。

このスクリプトでは 2010-04-01T09:00:00-07:00 という ISO8601フォーマットの文字列が渡されています。

import pytz
import iso8601
from datetime import datetime

txt = '2010-04-01T09:00:00-07:00'
print('Original Text  : ' + txt)

オリジナルテキストとしてそれをそのまま表示しています。

次に iso8601 パッケージの parse_date 関数によって、文字列の内容を読み取り datetime オブジェクトにします。

# Parse Text
p = iso8601.parse_date(txt)
print('Parsed date    : ' + str(p))
print('UTC Offset     : ' + str(p.utcoffset()))

これらの出力は次の通りです。

Parsed date    : 2010-04-01 09:00:00-07:00
UTC Offset     : -1 day, 17:00:00

確かに内容が取り込まれています。UTC からのオフセットは、つまりタイムゾーンになるわけですが、これも確かに認識されていることがわかります。

ただ、「UTC からマイナス 7 時間」と言えば簡単に思えますが、出力は「1 日マイナスでプラス 17時間」という内容が書いています。24時間マイナスで、そこからプラス 17 時間ということで、 確かに差し引きマイナス 7 時間ですが、やや分かりにくいですね。

UNIX タイムスタンプも次の通りとれています。

# UNIX Timestamp
ts = int(p.timestamp())
print('UNIX timestamp : ' + str(ts))
UNIX timestamp : 1270137600

UNIX タイムスタンプは UTC 時刻の 1970 年 1 月 1 日午前 0 時 0 分 0 秒からの経過秒です。

さらに UNIX タイムスタンプから、また ISO フォーマットに戻すには次のようにします。

次の例では同じ UNIX タイムスタンプ UTC 時刻とロサンゼルス時刻を ISO フォーマットで表示しています。

# ISO Format - UTC
utc_tz = pytz.timezone('UTC')
d = datetime.fromtimestamp(ts, utc_tz).isoformat()
print('ISO Format UTC : ' + d)

# ISO Format - LA
la_tz = pytz.timezone('America/Los_Angeles')
d = datetime.fromtimestamp(ts, la_tz).isoformat()
print('ISO Format LA  : ' + d)
ISO Format UTC : 2010-04-01T16:00:00+00:00
ISO Format LA  : 2010-04-01T09:00:00-07:00

確かに元の文字列から UNIX タイムスタンプまで変換した後からでも、もとの表記に戻せています。

以上、ISO8601 フォーマットでの文字列の扱い方について説明しました。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Python 入門