Pythonのdatetimeを用いて,日時をISO 8601で表現します.
aware (タイムゾーンあり) か native (タイムゾーンなし) を意識し,isoformat()
とfromisoformat()
の動作を確認するユニットテストを作成しました.
import datetime import unittest class ISOFormatTest(unittest.TestCase): def test_datetime_iso_format(self): utc = datetime.timezone.utc jst = datetime.timezone(offset=datetime.timedelta(hours=9)) tests = [ (datetime.datetime(2000, 1, 1, 0, 0, 0), "2000-01-01T00:00:00"), (datetime.date(2000, 1, 1), "2000-01-01"), (datetime.time(0, 0, 0), "00:00:00"), ( datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=utc), "2000-01-01T00:00:00+00:00", ), ( datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=jst), "2000-01-01T00:00:00+09:00", ), # datetime.date does not have tzinfo. (datetime.time(0, 0, 0, tzinfo=utc), "00:00:00+00:00"), ] for a, b in tests: with self.subTest(a=a): self.assertEqual(a.isoformat(), b) def test_iso_format_timespec(self): utc = datetime.timezone.utc dt = datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=utc) tests = [ ("auto", "2000-01-01T00:00:00+00:00"), ("hours", "2000-01-01T00+00:00"), ("minutes", "2000-01-01T00:00+00:00"), ("seconds", "2000-01-01T00:00:00+00:00"), ("milliseconds", "2000-01-01T00:00:00.000+00:00"), ("microseconds", "2000-01-01T00:00:00.000000+00:00"), ] for a, b in tests: with self.subTest(a=a): self.assertEqual(dt.isoformat(timespec=a), b) def test_datetime_from_iso_format(self): utc = datetime.timezone.utc jst = datetime.timezone(offset=datetime.timedelta(hours=9)) tests = [ (datetime.datetime(2000, 1, 1, 0, 0, 0), "2000-01-01T00:00:00"), ( datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=utc), "2000-01-01T00:00:00+00:00", ), ( datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=jst), "2000-01-01T00:00:00+09:00", ), ] for a, b in tests: with self.subTest(a=a): self.assertEqual(datetime.datetime.fromisoformat(b), a) def test_date_from_iso_format(self): tests = [ (datetime.date(2000, 1, 1), "2000-01-01"), ] for a, b in tests: with self.subTest(a=a): self.assertEqual(datetime.date.fromisoformat(b), a) def test_time_from_iso_format(self): utc = datetime.timezone.utc tests = [ (datetime.time(0, 0, 0), "00:00:00"), (datetime.time(0, 0, 0, tzinfo=utc), "00:00:00+00:00"), ] for a, b in tests: with self.subTest(a=a): self.assertEqual(datetime.time.fromisoformat(b), a)
実行したところ,問題なく動作しました.
% sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 % python3 --version Python 3.9.7 % python3 -m unittest test_datetime ..... ---------------------------------------------------------------------- Ran 5 tests in 0.001s OK
UTCの日時を示す場合は時刻の後ろに Z を添える表現をよく見ますが,2000-01-01T00:00:00+00:00
のように+00:00を添えて出力するようです.