datetime --- 基本的な日付と時間の型

ソースコード: Lib/datetime.py


datetime モジュールは、日付や時刻を操作するためのクラスを提供しています。

日付や時刻に対する算術がサポートされている一方、実装では出力のフォーマットや操作のための効率的な属性の抽出に重点を置いています。

Tip

書式コード に飛ぶ。

参考

calendar モジュール

汎用のカレンダー関連関数。

time モジュール

時刻へのアクセスと変換。

zoneinfo モジュール

IANAタイムゾーンデータベースを表す具体的なタイムゾーン。

dateutil パッケージ

拡張タイムゾーンと構文解析サポートのあるサードパーティーライブラリ。

DateType パッケージ

異なる静的な型を導入するサードパーティライブラリです。 例えば、静的型チェッカー が naive な日時と aware な日時を区別できるようになります。

aware オブジェクトと naive オブジェクト

日時のオブジェクトは、それらがタイムゾーンの情報を含んでいるかどうかによって "aware" あるいは "naive" に分類されます。

タイムゾーンや夏時間の情報のような、アルゴリズム的で政治的な適用可能な時間調節に関する知識を持っているため、 aware オブジェクトは他の aware オブジェクトとの相対関係を特定できます。 aware オブジェクトは解釈の余地のない特定の実時刻を表現します。 [1]

naive オブジェクトには他の日付時刻オブジェクトとの相対関係を把握するのに足る情報が含まれません。あるプログラム内の数字がメートルを表わしているのか、マイルなのか、それとも質量なのかがプログラムによって異なるように、naive オブジェクトが協定世界時 (UTC) なのか、現地時間なのか、それとも他のタイムゾーンなのかはそのプログラムに依存します。Naive オブジェクトはいくつかの現実的な側面を無視してしまうというコストを無視すれば、簡単に理解でき、うまく利用することができます。

aware オブジェクトが必要なアプリケーションのために、datetime と time オブジェクトには、省略可能なタイムゾーン情報の属性 tzinfo があります。 この属性には、抽象クラス tzinfo のサブクラスのインスタンスを設定できます。 これらの tzinfo オブジェクトは、UTC 時刻からのオフセット、タイムゾーン名、夏時間が適用されているかどうかの情報を保持します。

datetime モジュールが提供する具象 tzinfo クラスは timezone だけです。 timezone クラスは、UTC 自体や北米の EST、EDT など、UTC からのオフセットが固定された単純なタイムゾーンを表現できます。 より詳細なタイムゾーンの扱いはアプリケーションに任されています。 世界各地の時刻調整のルールは合理的というより政治的なもので、頻繁に変更されます。 UTC を除けば、あらゆるアプリケーションに適した標準はありません。

定数

datetime モジュールでは以下の定数を公開しています:

datetime.MINYEAR

date や datetime オブジェクトで許されている、年を表現する最小の数字です。 MINYEAR は1です。

datetime.MAXYEAR

date や datetime オブジェクトで許されている、年を表現する最大の数字です。 MAXYEAR は9999です。

datetime.UTC

UTCタイムゾーンシングルトン datetime.timezone.utc の別名。

Added in version 3.11.

利用可能な型

class datetime.date

理想的な naive な日付で、これまでもこれからも現在のグレゴリオ暦 (Gregorian calender) が有効であることを仮定しています。 属性は year, month,および day です。

class datetime.time

理想的な時刻で、特定の日から独立しており、毎日が厳密に 24*60*60 秒であると仮定しています。("うるう秒: leap seconds" の概念はありません。) 属性は hour, minute, second, microsecond, および tzinfo です。

class datetime.datetime

日付と時刻を組み合わせたものです。 属性は year, month, day, hour, minute, second, microsecond, および tzinfo です。

class datetime.timedelta

datetime あるいは date クラスの二つのインスタンス間の時間差をマイクロ秒精度で表す経過時間値です。

class datetime.tzinfo

タイムゾーン情報オブジェクトの抽象基底クラスです。 datetime および time クラスで用いられ、カスタマイズ可能な時刻修正の概念 (たとえばタイムゾーンや夏時間の計算) を提供します。

class datetime.timezone

tzinfo 抽象基底クラスを UTC からの固定オフセットとして実装するクラスです。

Added in version 3.2.

これらの型のオブジェクトは変更不可能 (immutable) です。

サブクラスの関係:

timedelta、tzinfo、time、date は object を継承し、timezone は tzinfo を継承し、datetime は date を継承します。

共通の性質

date 型、datetime 型、time 型、timezone 型には共通する特徴があります:

  • これらの型のオブジェクトは変更不可能 (immutable) です。

  • これらの型のオブジェクトは ハッシュ可能 であり、辞書のキーとして使えることになります。

  • これらの型のオブジェクトは pickle モジュールを利用して効率的な pickle 化をサポートしています。

オブジェクトが aware か naive かの判定

date 型のオブジェクトは常に naive です。

time 型あるいは datetime 型のオブジェクトは aware か naive のどちらかです。

datetime オブジェクト d は、d.utcoffset() が None を返さなければ aware です。 それ以外の場合、d は naive です。

time オブジェクト t は、t.utcoffset() が None を返さなければ aware です。 それ以外の場合、t は naive です。

aware なオブジェクトと naive なオブジェクトの区別は timedelta オブジェクトにはあてはまりません。

timedelta オブジェクト

timedelta オブジェクトは経過時間、すなわち二つの datetime または date のインスタンスの差を表します。

class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

全ての引数がオプションで、デフォルト値は0です。 引数は整数、浮動小数点数でもよく、正でも負でもかまいません。

days, seconds, microseconds だけが内部的に保持されます。 引数は以下のようにして変換されます:

  • 1 ミリ秒は 1000 マイクロ秒に変換されます。

  • 1 分は 60 秒に変換されます。

  • 1 時間は 3600 秒に変換されます。

  • 1 週間は 7 日に変換されます。

さらに、値が一意に表されるように days, seconds, microseconds が以下のように正規化されます

  • 0 <= microseconds < 1000000

  • 0 <= seconds < 3600*24 (一日中の秒数)

  • -999999999 <= days <= 999999999

次の例は、 days, seconds, microseconds に加えて任意の引数がどう "集約" され、最終的に3つの属性に正規化されるかの説明をしています:

>>> import datetime as dt
>>> delta = dt.timedelta(
...     days=50,
...     seconds=27,
...     microseconds=10,
...     milliseconds=29000,
...     minutes=5,
...     hours=8,
...     weeks=2
... )
>>> # days、seconds、microseconds だけが残る
>>> delta
datetime.timedelta(days=64, seconds=29156, microseconds=10)

Tip

モジュールとクラスの混同を避けるため、import datetime や from datetime import datetime ではなく import datetime as dt を使用します。 How I Import Python’s datetime Module を参照してください。

引数に浮動小数点数があり、マイクロ秒未満の端数が生じる場合は、すべての引数の端数を合計し、最も近いマイクロ秒に丸めます。 ちょうど中間の値は偶数側に丸めます。 浮動小数点数の引数がなければ、変換と正規化は厳密に行われ、情報は失われません。

日の値を正規化した結果、指定された範囲の外側になった場合には、 OverflowError が送出されます。

負の値を正規化すると、最初は混乱するような値になります。例えば:

>>> import datetime as dt
>>> d = dt.timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

timedelta オブジェクトの文字列表現は分かりにくいことがあるため、以下のレシピで読みやすい形式にできます:

>>> def pretty_timedelta(td):
...     if td.days >= 0:
...         return str(td)
...     return f'-({-td!s})'
...
>>> d = timedelta(hours=-1)
>>> str(d)  # 人には分かりにくい
'-1 day, 23:00:00'
>>> pretty_timedelta(d)
'-(1:00:00)'

以下にクラス属性を示します:

timedelta.min

最小の値を表す timedelta オブジェクトで、 timedelta(-999999999) です。

timedelta.max

最大の値を表す timedelta オブジェクトで、 timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999) です。

timedelta.resolution

timedelta オブジェクトが等しくならない最小の時間差で、 timedelta(microseconds=1) です。

正規化のために、 timedelta.max は -timedelta.min より大きいことに注意してください。 -timedelta.max は timedelta オブジェクトとして表現することができません。

インスタンスの属性 (読み出しのみ):

timedelta.days

両端値を含む-999,999,999 から 999,999,999 の間

timedelta.seconds

両端値を含む 0 から 86,399 の間

注意

本来は total_seconds() の値を取得するつもりで、誤ってこの属性を使用してしまうバグは比較的よくあります:

>>> import datetime as dt
>>> duration = dt.timedelta(seconds=11235813)
>>> duration.days, duration.seconds
(130, 3813)
>>> duration.total_seconds()
11235813.0
timedelta.microseconds

両端値を含む 0 から 999,999 の間

サポートされている演算を以下に示します:

演算

結果

t1 = t2 + t3

t2 と t3 の和。演算後、t1 - t2 == t3 および t1 - t3 == t2 は真になります。(1)

t1 = t2 - t3

t2 と t3 の差。演算後、t1 == t2 - t3 および t2 == t1 + t3 は真になります。 (1)(6)

t1 = t2 * i または t1 = i * t2

時間差と整数の積。演算後、t1 // i == t2 は i != 0 であれば真となります。

一般的に、t1 * i == t1 * (i-1) + t1 は真となります。(1)

t1 = t2 * f または t1 = f * t2

時間差と浮動小数点の積。結果は最近接偶数への丸めを利用して最も近い timedelta.resolution の倍数に丸められます。

f = t2 / t3

t2 を t3 で除算 (3) したもの。float オブジェクトを返します。

t1 = t2 / f または t1 = t2 / i

時間差を浮動小数点や整数で除したもの。結果は最近接偶数への丸めを利用して最も近い timedelta.resolution の倍数に丸められます。

t1 = t2 // i または t1 = t2 // t3

floor が計算され、余りは (もしあれば) 捨てられます。後者の場合、整数が返されます。(3)

t1 = t2 % t3

剰余が timedelta オブジェクトとして計算されます。(3)

q, r = divmod(t1, t2)

商と剰余が計算されます: q = t1 // t2 (3) と r = t1 % t2 。q は整数で r は timedelta オブジェクトです。

+t1

同じ値を持つ timedelta オブジェクトを返します。(2)

-t1

timedelta(-t1.days, -t1.seconds, -t1.microseconds)、および t1 * -1 と同じです。 (1)(4)

abs(t)

t.days >= 0 のときには +t, t.days < 0 のときには -t となります。(2)

str(t)

[D day[s], ][H]H:MM:SS[.UUUUUU] という形式の文字列を返します。t が負の値の場合は D は負の値となります。(5)

repr(t)

timedelta オブジェクトの文字列表現を返します。その文字列は、正規の属性値を持つコンストラクタ呼び出しのコードになっています。

注釈:

  1. この演算は正確ですが、オーバフローするかもしれません。

  2. この演算は正確であり、オーバフローし得ません。

  3. 0 による除算は ZeroDivisionError を送出します。

  4. -timedelta.max は timedelta オブジェクトで表現することができません。

  5. timedelta オブジェクトの文字列表現は内部表現に類似した形に正規化されます。そのため負の timedelta は少し変な結果になります。例えば:

    >>> timedelta(hours=-5)
    datetime.timedelta(days=-1, seconds=68400)
    >>> print(_)
    -1 day, 19:00:00
    
  6. t3 が timedelta.max のときを除けば、式 t2 - t3 は常に、式 t2 + (-t3) と同等です。t3 が timedelta.max の場合、前者の式は結果の値が出ますが、後者はオーバーフローを起こします。

上に列挙した操作に加え timedelta オブジェクトは date および datetime オブジェクトとの間で加減算をサポートしています (下を参照してください)。

バージョン 3.2 で変更: timedelta オブジェクトを別の timedelta オブジェクトで割る切り捨て除算と真の除算、および剰余演算と divmod() 関数がサポートされるようになりました。 timedelta オブジェクトと float オブジェクトの真の除算および乗算もサポートされるようになりました。

timedelta オブジェクトは等価性と順序の比較をサポートします。

ブール演算コンテキストでは、 timedelta オブジェクトは timedelta(0) に等しくない場合かつそのときに限り真となります。

インスタンスメソッド:

timedelta.total_seconds()

経過時間に含まれる秒数の合計を返します。 td / timedelta(seconds=1) と等価です。 秒以外の時間単位には、除算の形式を直接使用してください (例えば td / timedelta(microseconds=1))。

非常に長い期間 (多くのプラットフォームでは270年以上) については、このメソッドはマイクロ秒の精度を失うことがあることに注意してください。

Added in version 3.2.

使用例: timedelta

正規化の追加の例です:

>>> # another_year の各成分の合計はちょうど 365 日になる
>>> import datetime as dt
>>> year = dt.timedelta(days=365)
>>> another_year = dt.timedelta(weeks=40, days=84, hours=23,
...                             minutes=50, seconds=600)
>>> year == another_year
True
>>> year.total_seconds()
31536000.0

timedelta の計算の例です:

>>> import datetime as dt
>>> year = dt.timedelta(days=365)
>>> ten_years = 10 * year
>>> ten_years
datetime.timedelta(days=3650)
>>> ten_years.days // 365
10
>>> nine_years = ten_years - year
>>> nine_years
datetime.timedelta(days=3285)
>>> three_years = nine_years // 3
>>> three_years, three_years.days // 365
(datetime.timedelta(days=1095), 3)

date オブジェクト

date オブジェクトは、両方向に無期限に拡張された現在のグレゴリオ暦という理想化された暦の日付 (年月日) を表します。

1 年 1 月 1 日は日番号 1、1 年 1 月 2 日は日番号 2 と呼ばれ、他も同様です。 [2]

class datetime.date(year, month, day)

全ての引数が必須です。 引数は整数で、次の範囲に収まっていなければなりません:

  • MINYEAR <= year <= MAXYEAR

  • 1 <= month <= 12

  • 1 <= day <= 指定された月と年における日数

範囲を超えた引数を与えた場合、 ValueError が送出されます。

その他のコンストラクタ (すべてクラスメソッド):

classmethod date.today()

現在のローカルな日付を返します。

date.fromtimestamp(time.time()) と等価です。

classmethod date.fromtimestamp(timestamp)

time.time() の返り値などの POSIX timestamp に対応するローカルな日付を返します。

timestamp がプラットフォームの C 関数 localtime() がサポートする値の範囲から外れていた場合、 OverflowError を送出するかもしれません。また localtime() 呼び出しが失敗した場合には OSError を送出するかもしれません。この範囲は通常は 1970 年から 2038 年までに制限されています。タイムスタンプの表記にうるう秒を含める非 POSIX なシステムでは、うるう秒は fromtimestamp() では無視されます。

バージョン 3.3 で変更: timestamp がプラットフォームの C 関数 localtime() のサポートする値の範囲から外れていた場合、 ValueError ではなく OverflowError を送出するようになりました。 localtime() の呼び出し失敗で ValueError ではなく OSError を送出するようになりました。

バージョン 3.15 で変更: timestamp として、整数や浮動小数点数だけでなく任意の実数を受け付けるようになりました。

classmethod date.fromordinal(ordinal)

先発グレゴリオ暦の序数 ordinal に対応する日付を返します。 1 年 1 月 1 日の序数を 1 とします。

1 <= ordinal <= date.max.toordinal() でない場合、 ValueError が送出されます。 任意の日付 d に対し、 date.fromordinal(d.toordinal()) == d となります。

classmethod date.fromisoformat(date_string)

以下の例外を除く、有効な ISO 8601 フォーマットで与えられた date_string に対応する date を返します :

  1. 精度の低い日付は現在サポートされていません(YYYY-MM, YYYY)。

  2. 拡張された日付表現は現在サポートされていません(±YYYYYY-MM-DD)。

  3. 序数の日付は現在サポートされていません(YYYY-OOO)。

例:

>>> import datetime as dt
>>> dt.date.fromisoformat('2019-12-04')
datetime.date(2019, 12, 4)
>>> dt.date.fromisoformat('20191204')
datetime.date(2019, 12, 4)
>>> dt.date.fromisoformat('2021-W01-1')
datetime.date(2021, 1, 4)

Added in version 3.7.

バージョン 3.11 で変更: 以前はこのメソッドは YYYY-MM-DD フォーマットのみをサポートしていました。

classmethod date.fromisocalendar(year, week, day)

year、week、day で指定した ISO 暦の日付に対応する date を返します。 これは date.isocalendar() 関数の逆操作です。

Added in version 3.8.

classmethod date.strptime(date_string, format)

format に従って date_string を解析し、対応する date を返します。 次の式と等価です。

date(*(time.strptime(date_string, format)[0:3]))

date_string と format が time.strptime() で構文解析できない場合や、この関数が時刻タプルを返してこない場合には ValueError を送出します。strftime() と strptime() の動作 および date.fromisoformat() も参照してください。

注釈

format が年を指定せずに日 (%d) を指定している場合、ValueError を送出します。 これは、月と日だけを解析しようとするコードで 4 年ごとに起きるうるう年のバグを避けるためです。 書式に年がない場合に使用するデフォルトの年が、うるう年ではないことが原因です。 回避するには、format に常に年を含めてください。 年を持たない date_string の値を解析する場合は、解析する前にうるう年の年を明示的に追加してください:

>>> import datetime as dt
>>> date_string = "02/29"
>>> when = dt.date.strptime(f"{date_string};1984", "%m/%d;%Y")  # うるう年のバグを回避する。
>>> when.strftime("%B %d")
'February 29'

Added in version 3.14.

以下にクラス属性を示します:

date.min

表現できる最も古い日付で、date(MINYEAR, 1, 1) です。

date.max

表現できる最も新しい日付で、date(MAXYEAR, 12, 31) です。

date.resolution

等しくない日付オブジェクト間の最小の差で、timedelta(days=1) です。

インスタンスの属性 (読み出しのみ):

date.year

両端値を含む MINYEAR から MAXYEAR までの値です。

date.month

両端値を含む 1 から 12 までの値です。

date.day

1 から与えられた月と年における日数までの値です。

サポートされている演算を以下に示します:

演算

結果

date2 = date1 + timedelta

date2 は date1 の timedelta.days 日後になります。(1)

date2 = date1 - timedelta

date2 + timedelta == date1 であるような日付 date2 を計算します。(2)

timedelta = date1 - date2

(3)

date1 == date2
date1 != date2

等価性の比較。(4)

date1 < date2
date1 > date2
date1 <= date2
date1 >= date2

順序の比較。(5)

注釈:

  1. date2 は、 timedelta.days > 0 の場合は進む方向に、 timedelta.days < 0 の場合は戻る方向に移動します。 演算後は date2 - date1 == timedelta.days が成立します。 timedelta.seconds および timedelta.microseconds は無視されます。 date2.year が MINYEAR より小さくなったり、 MAXYEAR より大きくなってしまう場合には OverflowError が送出されます。

  2. timedelta.seconds と timedelta.microseconds は無視されます。

  3. この演算は厳密で、オーバフローしません。timedelta.seconds および timedelta.microseconds は 0 で、演算後には date2 + timedelta == date1 となります。

  4. 同じ日を表す date オブジェクトは等しいです。

    datetime のインスタンスではない date オブジェクトは、同じ日を表していても、datetime オブジェクトとは決して等価にはなりません。

  5. date1 が時間的に date2 より前にある場合、date1 は date2 より小さいとみなされます。 言い換えると、date1.toordinal() < date2.toordinal() の場合に限り date1 < date2 となります。

    datetime のインスタンスではない date オブジェクトと、datetime オブジェクトとの順序比較は、TypeError を送出します。

バージョン 3.13 で変更: Comparison between datetime object and an instance of the date subclass that is not a datetime subclass no longer converts the latter to date, ignoring the time part and the time zone. The default behavior can be changed by overriding the special comparison methods in subclasses.

ブール値の文脈では、すべての date オブジェクトは真とみなされます。

インスタンスメソッド:

date.replace(year=self.year, month=self.month, day=self.day)

指定したパラメータだけを更新し、それ以外は同じ値を持つ新しい date オブジェクトを返します。

以下はプログラム例です:

>>> import datetime as dt
>>> d = dt.date(2002, 12, 31)
>>> d.replace(day=26)
datetime.date(2002, 12, 26)

汎用関数 copy.replace() も date オブジェクトをサポートしています。

date.timetuple()

time.localtime() が返すような time.struct_time を返します。

時分秒が 0 で、 DST フラグが -1 です。

d.timetuple() は次の式と等価です:

time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))

ここで、 yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 は本年の 1 月 1 日を 1 としたときの日付番号です。

date.toordinal()

先発グレゴリオ暦における日付序数を返します。 1 年の 1 月 1 日が序数 1 となります。任意の date オブジェクト d について、 date.fromordinal(d.toordinal()) == d となります。

date.weekday()

月曜日を 0、日曜日を 6 として、曜日を整数で返します。例えば、 date(2002, 12, 4).weekday() == 2 であり、水曜日を示します。 isoweekday() も参照してください。

date.isoweekday()

月曜日を 1,日曜日を 7 として、曜日を整数で返します。例えば、 date(2002, 12, 4).isoweekday() == 3 であり、水曜日を示します。 weekday(), isocalendar() も参照してください。

date.isocalendar()

year、week、weekday の3つで構成された named tuple を返します。

ISO 暦はグレゴリオ暦の変種として広く用いられています。 [3]

ISO 年は完全な週が 52 週または 53 週あり、週は月曜から始まって日曜に終わります。ISO 年でのある年における最初の週は、その年の木曜日を含む最初の (グレゴリオ暦での) 週となります。この週は週番号 1 と呼ばれ、この木曜日での ISO 年はグレゴリオ暦における年と等しくなります。

例えば、2004 年は木曜日から始まるため、ISO 年の最初の週は 2003 年 12 月 29 日、月曜日から始まり、2004 年 1 月 4 日、日曜日に終わります

>>> import datetime as dt
>>> dt.date(2003, 12, 29).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=1)
>>> dt.date(2004, 1, 4).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=7)

バージョン 3.9 で変更: 結果が タプル から named tuple へ変更されました。

date.isoformat()

日付を ISO 8601 書式の YYYY-MM-DD で表した文字列を返します:

>>> import datetime as dt
>>> dt.date(2002, 12, 4).isoformat()
'2002-12-04'
date.__str__()

date オブジェクト d において、str(d) は d.isoformat() と等価です。

date.ctime()

日付を表す文字列を返します:

>>> import datetime as dt
>>> dt.date(2002, 12, 4).ctime()
'Wed Dec  4 00:00:00 2002'

d.ctime() は次の式と等価です:

time.ctime(time.mktime(d.timetuple()))

これが等価になるのは、 (time.ctime() に呼び出され、 date.ctime() に呼び出されない) ネイティブの C 関数 ctime() が C 標準に準拠しているプラットフォーム上でです。

date.strftime(format)

明示的な書式文字列で制御された、日付を表現する文字列を返します。 時間、分、秒を表す書式コードは値 0 になります。 strftime() と strptime() の動作 および date.isoformat() も参照してください。

date.__format__(format)

date.strftime() と等価です。 これにより、 フォーマット済み文字列リテラル の中や str.format() を使っているときに date オブジェクトの書式文字列を指定できます。 strftime() と strptime() の動作 および date.isoformat() も参照してください。

使用例: date

イベントまでの日数を数える例を示します:

>>> import time
>>> import datetime as dt
>>> today = dt.date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == dt.date.fromtimestamp(time.time())
True
>>> my_birthday = dt.date(today.year, 6, 24)
>>> if my_birthday < today:
...     my_birthday = my_birthday.replace(year=today.year + 1)
...
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202

さらなる date を使う例:

>>> import datetime as dt
>>> d = dt.date.fromordinal(730920) # 0001 年 1 月 1 日から数えて 730920 日目
>>> d
datetime.date(2002, 3, 11)

>>> # 文字列出力の書式に関するメソッド
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> d.ctime()
'Mon Mar 11 00:00:00 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'

>>> # さまざまな暦の「成分」を取り出すメソッド
>>> t = d.timetuple()
>>> for i in t:
...     print(i)
2002                # 年
3                   # 月
11                  # 日
0
0
0
0                   # 曜日 (0 = 月曜日)
70                  # 年内の 70 日目
-1
>>> ic = d.isocalendar()
>>> for i in ic:
...     print(i)
2002                # ISO の年
11                  # ISO の週番号
1                   # ISO の曜日番号 (1 = 月曜日)

>>> # date オブジェクトは不変であり、すべての操作は新しいオブジェクトを生成する
>>> d.replace(year=2005)
datetime.date(2005, 3, 11)

datetime オブジェクト

datetime オブジェクトは date オブジェクトおよび time オブジェクトの全ての情報が入っている単一のオブジェクトです。

date オブジェクトと同様に、datetime は現在のグレゴリオ暦を過去と未来の両方向に拡張した暦を仮定します。 また、time オブジェクトと同様に、datetime は毎日が厳密に 3600*24 秒であると仮定します。

以下にコンストラクタを示します:

class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

year, month, day 引数は必須です。 tzinfo は None または tzinfo サブクラスのインスタンスです。 残りの引数は次の範囲の整数でなければなりません:

  • MINYEAR <= year <= MAXYEAR,

  • 1 <= month <= 12,

  • 1 <= day <= 指定された月と年における日数,

  • 0 <= hour < 24,

  • 0 <= minute < 60,

  • 0 <= second < 60,

  • 0 <= microsecond < 1000000,

  • fold in [0, 1].

範囲を超えた引数を与えた場合、 ValueError が送出されます。

バージョン 3.6 で変更: fold パラメータが追加されました。

その他のコンストラクタ (すべてクラスメソッド):

classmethod datetime.today()

tzinfo が None である現在のローカルの日付および時刻を返します。

次と等価です:

datetime.fromtimestamp(time.time())

now(), fromtimestamp() も参照してください。

このメソッドの機能は now() と等価ですが、 tz 引数はありません。

classmethod datetime.now(tz=None)

現在のローカルな日時を返します。

省略可能な引数 tz が None または未指定の場合、このメソッドは today() と同様に動作します。 ただし可能であれば、time.time() のタイムスタンプ経由で得られる精度よりも高い精度で時刻を返します (例えば、C 関数 gettimeofday() を提供するプラットフォームでは可能な場合があります)。

tz が None でない場合、 tz は tzinfo のサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。

today() および utcnow() よりもこの関数を使う方が好ましいです。

注釈

基盤となる時計の精度によっては、datetime.now() を続けて呼び出しても同じ時点を返すことがあります。

classmethod datetime.utcnow()

tzinfo が None である現在の UTC の日付および時刻を返します。

このメソッドは now() と似ていますが、 naive な datetime オブジェクトとして現在の UTC 日付および時刻を返します。 aware な現在の UTC datetime は datetime.now(timezone.utc) を呼び出すことで取得できます。 now() も参照してください。

警告

naive な datetime オブジェクトは多くの datetime メソッドでローカルな時間として扱われるため、 aware な datetime を使って UTC の時刻を表すのが好ましいです。 そのため、 UTC での現在の時刻を表すオブジェクトの作成では datetime.now(timezone.utc) を呼び出す方法が推奨されます。

バージョン 3.12 で非推奨: 代わりに UTC を指定して datetime.now() を使用してください。

classmethod datetime.fromtimestamp(timestamp, tz=None)

time.time() が返すような、 POSIX タイムスタンプに対応するローカルな日付と時刻を返します。オプションの引数 tz が None であるか、指定されていない場合、タイムスタンプはプラットフォームのローカルな日付および時刻に変換され、返される datetime オブジェクトは naive なものになります。

tz が None でない場合、 tz は tzinfo のサブクラスのインスタンスでなければならず、タイムスタンプは tz のタイムゾーンに変換されます。

タイムスタンプがプラットフォームの C 関数 localtime() や gmtime() でサポートされている範囲を超えた場合、 fromtimestamp() は OverflowError を送出することがあります。この範囲はよく 1970 年から 2038 年に制限されています。 また localtime() や gmtime() が失敗した際は OSError を送出します。 うるう秒がタイムスタンプの概念に含まれている非 POSIX システムでは、 fromtimestamp() はうるう秒を無視します。 このため、秒の異なる二つのタイムスタンプが同一の datetime オブジェクトとなることが起こり得ます。 utcfromtimestamp() よりも、このメソッドの方が好ましいです。

バージョン 3.3 で変更: timestamp がプラットフォームの C 関数 localtime() もしくは gmtime() のサポートする値の範囲から外れていた場合、 ValueError ではなく OverflowError を送出するようになりました。 localtime() もしくは gmtime() の呼び出し失敗で ValueError ではなく OSError を送出するようになりました。

バージョン 3.6 で変更: fromtimestamp() は fold が 1 に設定されたインスタンスを返すことがあります。

バージョン 3.15 で変更: timestamp として、整数や浮動小数点数だけでなく任意の実数を受け付けるようになりました。

classmethod datetime.utcfromtimestamp(timestamp)

POSIX タイムスタンプに対応する、tzinfo が None の UTC での datetime を返します。(返されるオブジェクトは naive です。)

タイムスタンプがプラットフォームにおける C 関数 gmtime() でサポートされている範囲を超えている場合には OverflowError を、gmtime() が失敗した場合には OSError を送出します。 これはたいてい 1970 年から 2038 年に制限されています。

aware な datetime オブジェクトを得るには fromtimestamp() を呼んでください:

datetime.fromtimestamp(timestamp, timezone.utc)

POSIX 互換プラットフォームでは、これは以下の表現と等価です:

datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)

ただし、後者の式は常に年の全範囲 (MINYEAR から MAXYEAR まで、両端を含む) をサポートするという違いがあります。

警告

naive な datetime オブジェクトは多くの datetime メソッドでローカルな時間として扱われるため、 aware な datetime を使って UTC の時刻を表すのが好ましいです。 そのため、 UTC でのある特定のタイムスタンプを表すオブジェクトの作成では datetime.fromtimestamp(timestamp, tz=timezone.utc) を呼び出す方法が推奨されます。

バージョン 3.3 で変更: timestamp がプラットフォームの C 関数 gmtime() のサポートする値の範囲から外れていた場合、 ValueError ではなく OverflowError を送出するようになりました。 gmtime() の呼び出し失敗で ValueError ではなく OSError を送出するようになりました。

バージョン 3.15 で変更: timestamp として、整数や浮動小数点数だけでなく任意の実数を受け付けるようになりました。

バージョン 3.12 で非推奨: 代わりに UTC を指定して datetime.fromtimestamp() を使用してください。

classmethod datetime.fromordinal(ordinal)

1 年 1 月 1 日を序数 1 とする早期グレゴリオ暦序数に対応する datetime オブジェクトを返します。 1 <= ordinal <= datetime.max.toordinal() でなければ ValueError が送出されます。 返されるオブジェクトの時間、分、秒、およびマイクロ秒はすべて 0 で、 tzinfo は None となっています。

classmethod datetime.combine(date, time, tzinfo=time.tzinfo)

日付の各成分が指定した date オブジェクトと等しく、時刻の各成分が指定した time オブジェクトと等しい、新しい datetime オブジェクトを返します。 tzinfo 引数が指定されていれば、その値を結果の tzinfo 属性に設定します。 それ以外の場合、time 引数の tzinfo 属性を使用します。 date 引数が datetime オブジェクトの場合、その時刻の各成分と tzinfo 属性は無視されます。

任意の datetime オブジェクト d について、d == datetime.combine(d.date(), d.time(), d.tzinfo) となります。

バージョン 3.6 で変更: tzinfo 引数が追加されました。

classmethod datetime.fromisoformat(date_string)

以下の例外を除く、有効な ISO 8601 フォーマットで与えられた date_string に対応する datetime を返します :

  1. 小数の秒があるタイムゾーンオフセット。

  2. T セパレーターを他の1文字のユニコードに置き換えたもの。

  3. 少数の時と分はサポートされていません。

  4. 精度の低い日付は現在サポートされていません(YYYY-MM, YYYY)。

  5. 拡張された日付表現は現在サポートされていません(±YYYYYY-MM-DD)。

  6. 序数の日付は現在サポートされていません(YYYY-OOO)。

例:

>>> import datetime as dt
>>> dt.datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> dt.datetime.fromisoformat('20111104')
datetime.datetime(2011, 11, 4, 0, 0)
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23Z')
datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc)
>>> dt.datetime.fromisoformat('20111104T000523')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> dt.datetime.fromisoformat('2011-W01-2T00:05:23.283')
datetime.datetime(2011, 1, 4, 0, 5, 23, 283000)
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23+04:00')
datetime.datetime(2011, 11, 4, 0, 5, 23,
    tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

Added in version 3.7.

バージョン 3.11 で変更: 以前は、このメソッドは date.isoformat() または datetime.isoformat() が出力できる形式だけをサポートしていました。

classmethod datetime.fromisocalendar(year, week, day)

year、week、day で指定した ISO 暦の日付に対応する datetime を返します。 日時の日付以外の成分には、通常のデフォルト値が設定されます。 これは datetime.isocalendar() 関数の逆操作です。

Added in version 3.8.

classmethod datetime.strptime(date_string, format)

date_string に対応した datetime を返します。 format にしたがって構文解析されます。

format がマイクロ秒やタイムゾーン情報を含まない場合は、以下と等価です:

datetime(*(time.strptime(date_string, format)[0:6]))

date_string と format が time.strptime() で構文解析できない場合や、この関数が時刻タプルを返してこない場合には ValueError を送出します。strftime() と strptime() の動作 および datetime.fromisoformat() も参照してください。

バージョン 3.15 で変更: format が年を指定せずに日 (%d) を指定している場合、ValueError を送出します。 これは、月と日だけを解析しようとするコードで 4 年ごとに起きるうるう年のバグを避けるためです。 書式に年がない場合に使用するデフォルトの年が、うるう年ではないことが原因です。 回避するには、format に常に年を含めてください。 年を持たない date_string の値を解析する場合は、解析する前にうるう年の年を明示的に追加してください:

>>> import datetime as dt
>>> date_string = "02/29"
>>> when = dt.datetime.strptime(f"{date_string};1984", "%m/%d;%Y")  # うるう年のバグを回避する。
>>> when.strftime("%B %d")
'February 29'

以下にクラス属性を示します:

datetime.min

表現できる最も古い datetime で、 datetime(MINYEAR, 1, 1, tzinfo=None) です。

datetime.max

表現できる最も新しい datetime で、 datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None) です。

datetime.resolution

等しくない datetime オブジェクト間の最小の差で、 timedelta(microseconds=1) です。

インスタンスの属性 (読み出しのみ):

datetime.year

両端値を含む MINYEAR から MAXYEAR までの値です。

datetime.month

両端値を含む 1 から 12 までの値です。

datetime.day

1 から与えられた月と年における日数までの値です。

datetime.hour

in range(24) を満たします。

datetime.minute

in range(60) を満たします。

datetime.second

in range(60) を満たします。

datetime.microsecond

in range(1000000) を満たします。

datetime.tzinfo

datetime コンストラクタに tzinfo 引数として与えられたオブジェクトになり、何も渡されなかった場合には None になります。

datetime.fold

[0, 1] のどちらかです。 繰り返し期間中の実時間の曖昧さ除去に使われます。 (繰り返し期間は、夏時間の終わりに時計が巻き戻るときや、現在のゾーンの UTC オフセットが政治的な理由で減少するときに発生します。) 0または1という値は、同じ実時間で表現される 2 つの時刻のうちのそれぞれ早い方または遅い方を表します。

Added in version 3.6.

サポートされている演算を以下に示します:

演算

結果

datetime2 = datetime1 + timedelta

(1)

datetime2 = datetime1 - timedelta

(2)

timedelta = datetime1 - datetime2

(3)

datetime1 == datetime2
datetime1 != datetime2

等価性の比較。(4)

datetime1 < datetime2
datetime1 > datetime2
datetime1 <= datetime2
datetime1 >= datetime2

順序の比較。(5)

  1. datetime2 は datetime1 から時間 timedelta 移動したもので、timedelta.days > 0 の場合未来へ、timedelta.days < 0 の場合過去へ移動します。 結果は入力の datetime と同じ tzinfo 属性を持ち、演算後には datetime2 - datetime1 == timedelta となります。 datetime2.year が MINYEAR よりも小さいか、 MAXYEAR より大きい場合には OverflowError が送出されます。 入力が aware なオブジェクトの場合でもタイムゾーン修正は全く行われません。

  2. datetime2 + timedelta == datetime1 となるような datetime2 を計算します。 ちなみに、結果は入力の datetime と同じ tzinfo 属性を持ち、入力が aware だとしてもタイムゾーン修正は全く行われません。

  3. datetime から datetime を引く減算は、両方のオペランドが naive であるか、両方が aware である場合にのみ定義されます。 一方が aware で他方が naive の場合は、TypeError を送出します。

    両方が naive の場合、または両方が aware で同じ tzinfo 属性を持つ場合、tzinfo 属性は無視され、結果は datetime2 + t == datetime1 を満たす timedelta オブジェクト t となります。 この場合、タイムゾーンの調整は行われません。

    両方が aware で異なる tzinfo 属性を持つ場合、a-b は、先に a と b を naive な UTC の日時に変換したかのように動作します。 結果は (a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset()) となりますが、実装ではオーバーフローが起きない点が異なります。

  4. datetime オブジェクトはタイムゾーンを考慮して同じ日付と時刻を表す場合、等しいです。

    naive な datetime オブジェクトと aware なものが等しくなることはありません。

    比較対象が両方とも aware で同じ tzinfo 属性を持つ場合、tzinfo と fold 属性を無視して、元の日時を比較します。 比較対象が両方とも aware で異なる tzinfo 属性を持つ場合、先に UTC の日時に変換したかのように比較しますが、実装ではオーバーフローが起きない点が異なります。 繰り返される時間帯にある datetime インスタンスが、別のタイムゾーンの datetime インスタンスと等しくなることはありません。

  5. タイムゾーンを考慮して、datetime1 が時刻として datetime2 よりも前を表す場合に、datetime1 は datetime2 よりも小さいと見なされます。

    naive な datetime オブジェクトと aware なものの順序比較は、TypeError を送出します。

    比較対象が両方とも aware で同じ tzinfo 属性を持つ場合、tzinfo と fold 属性を無視して、元の日時を比較します。 比較対象が両方とも aware で異なる tzinfo 属性を持つ場合、先に UTC の日時に変換したかのように比較しますが、実装ではオーバーフローが起きない点が異なります。

バージョン 3.3 で変更: aware な datetime インスタンスと naive な datetime インスタンスの等価比較では TypeError は送出されません。

バージョン 3.13 で変更: Comparison between datetime object and an instance of the date subclass that is not a datetime subclass no longer converts the latter to date, ignoring the time part and the time zone. The default behavior can be changed by overriding the special comparison methods in subclasses.

インスタンスメソッド:

datetime.date()

同じ年、月、日の date オブジェクトを返します。

datetime.time()

同じhour、minute、second、microsecond 及び foldを持つ time オブジェクトを返します。 tzinfo は None です。 timetz() も参照してください。

バージョン 3.6 で変更: 値 foldは返される time オブジェクトにコピーされます。

datetime.timetz()

同じhour、minute、second、microsecond、fold および tzinfo 属性を持つ time オブジェクトを返します。 time() メソッドも参照してください。

バージョン 3.6 で変更: 値 foldは返される time オブジェクトにコピーされます。

datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)

指定したパラメータだけを更新し、それ以外は同じ属性を持つ新しい datetime オブジェクトを返します。 tzinfo=None を指定すると、日付と時刻のデータを変換せずに、aware な日時から naive な日時を作成できます。

datetime オブジェクトは汎用的な関数 copy.replace() にもサポートされています。

バージョン 3.6 で変更: fold パラメータが追加されました。

datetime.astimezone(tz=None)

tz を新たに tzinfo 属性 として持つ datetime オブジェクトを返します。 日付および時刻データを調整して、返り値が self と同じ UTC 時刻を持ち、 tz におけるローカルな時刻を表すようにします。

もし与えられた場合、 tz は tzinfo のサブクラスのインスタンスでなければならず、 インスタンスの utcoffset() および dst() メソッドは None を返してはなりません。 self が naive の場合は、システムのタイムゾーンの時刻を表すものとして扱われます。

引数無し (もしくは tz=None の形 ) で呼び出された場合、システムのローカルなタイムゾーンが変更先のタイムゾーンだと仮定されます。 変換後の datetime インスタンスの .tzinfo 属性には、 OS から取得したゾーン名とオフセットを持つ timezone インスタンスが設定されます。

self.tzinfo が tz の場合、 self.astimezone(tz) は self に等しくなります。つまり、date および time に対する調整は行われません。そうでない場合、結果はタイムゾーン tz におけるローカル時刻で、 self と同じ UTC 時刻を表すようになります。これは、astz = dt.astimezone(tz) とした後、 astz - astz.utcoffset() は通常 dt - dt.utcoffset() と同じ date および time を持つことを示します。

単に timezone オブジェクト tz を datetime オブジェクト dt に追加したいだけで、日付や時刻データへの調整を行わないのなら、dt.replace(tzinfo=tz) を使ってください。単に aware な datetime オブジェクト dt から timezone オブジェクトを除去したいだけで、日付や時刻データの変換を行わないのなら、dt.replace(tzinfo=None) を使ってください。

デフォルトの tzinfo.fromutc() メソッドを tzinfo のサブクラスで上書きして, astimezone() が返す結果に影響を及ぼすことができます。エラーの場合を無視すると、 astimezone() は以下のように動作します:

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # self を UTC に変換し、新しい timezone オブジェクトを設定する。
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # UTC から tz のローカル時刻に変換する。
    return tz.fromutc(utc)

バージョン 3.3 で変更: tz が省略可能になりました。

バージョン 3.6 で変更: datetime.datetime.astimezone() メソッドを naive なインスタンスに対して呼び出せるようになりました。これは、システムのローカルな時間を表現していると想定されます。

datetime.utcoffset()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.utcoffset(self) を返します。 後者の式が None あるいは 1 日未満の大きさを持つ timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

datetime.dst()

tzinfo が None の場合 None を返し、そうでない場合には self.tzinfo.dst(self) を返します。 後者の式が None もしくは、1 日未満の大きさを持つ timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

バージョン 3.7 で変更: DST オフセットが分単位でなければならない制限が無くなりました。

datetime.tzname()

tzinfo が None の場合 None を返し、そうでない場合には self.tzinfo.tzname(self) を返します。 後者の式が None か文字列オブジェクトのいずれかを返さない場合には例外を送出します。

datetime.timetuple()

time.localtime() が返すような time.struct_time を返します。

d.timetuple() は次の式と等価です:

time.struct_time((d.year, d.month, d.day,
                  d.hour, d.minute, d.second,
                  d.weekday(), yday, dst))

ここで yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 はその年の1月1日を 1 としたときのその日の位置です。 返されるタプルの tm_isdst フラグは dst() メソッドに従って設定されます: tzinfo が None か dst() が None を返す場合、 tm_isdst は -1 に設定されます; そうでない場合、 dst() がゼロでない値を返すと tm_isdst は1となります; それ以外の場合には tm_isdst は0に設定されます。

datetime.utctimetuple()

datetime インスタンス d が naive の場合、d.dst() の返り値に関係なく tm_isdst が強制的に 0 になる点を除き、d.timetuple() と同じです。 UTC 時刻に DST が適用されることはありません。

d が aware の場合、d.utcoffset() を引いて d を UTC 時刻に正規化し、その時刻の time.struct_time を返します。 tm_isdst は強制的に 0 になります。 d.year が MINYEAR または MAXYEAR で、UTC への調整が年の境界を越える場合、OverflowError を送出することがあります。

警告

naive な datetime オブジェクトは多くの datetime メソッドでローカルな時間として扱われるため、 aware な datetime を使って UTC の時刻を表すのが好ましいです。 結果として、 datetime.utctimetuple() は誤解を招きやすい返り値を返すかもしれません。 UTC を表す naive な datetime があった場合、 datetime.replace(tzinfo=timezone.utc) で aware にしてから datetime.timetuple() を使えます。

datetime.toordinal()

先発グレゴリオ暦における日付序数を返します。self.date().toordinal() と同じです。

datetime.timestamp()

datetime インスタンスに対応する POSIX タイムスタンプを返します。 time.time() の返り値と同様に、返り値は float です。

naive な datetime インスタンスはローカル時刻を表すものとみなされ、このメソッドはプラットフォームの C 関数を使用して変換を行います。 多くのプラットフォームでは、datetime はプラットフォームの C 関数より広い範囲の値をサポートするため、遠い過去や未来の時刻に対して、このメソッドは OverflowError または OSError を送出することがあります。

aware な datetime インスタンスに対しては以下のように返り値が計算されます:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

注釈

UTC 時刻を表す naive な datetime インスタンスから直接 POSIX タイムスタンプを取得するメソッドはありません。 アプリケーションがその変換を使っており、システムのタイムゾーンが UTC に設定されていなかった場合、 tzinfo=timezone.utc を引数に与えることで POSIX タイムスタンプを取得できます:

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

もしくは直接タイムスタンプを計算することもできます:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

Added in version 3.3.

バージョン 3.6 で変更: The timestamp() method uses the fold attribute to disambiguate the times during a repeated interval.

バージョン 3.6 で変更: このメソッドは、変換にプラットフォームの C 関数 mktime() を使用しなくなりました。

datetime.weekday()

月曜日を 0、日曜日を 6 として、曜日を整数で返します。 self.date().weekday() と同じです。 isoweekday() も参照してください。

datetime.isoweekday()

月曜日を 1、日曜日を 7 として、曜日を整数で返します。 self.date().isoweekday() と等価です。 weekday() 、 isocalendar() も参照してください。

datetime.isocalendar()

year、week、weekday の3つで構成された named tuple を返します。 self.date().isocalendar() と等価です。

datetime.isoformat(sep='T', timespec='auto')

日時を ISO 8601 書式で表した文字列で返します:

  • microsecond が 0 でない場合は YYYY-MM-DDTHH:MM:SS.ffffff

  • microsecond が 0 の場合は YYYY-MM-DDTHH:MM:SS

utcoffset() が None を返さない場合は、文字列の後ろに UTC オフセットが追記されます:

  • microsecond が 0 でない場合は YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]

  • microsecond が 0 の場合は YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]

例:

>>> import datetime as dt
>>> dt.datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat()
'2019-05-18T15:17:08.132263'
>>> dt.datetime(2019, 5, 18, 15, 17, tzinfo=dt.timezone.utc).isoformat()
'2019-05-18T15:17:00+00:00'

オプションの引数 sep (デフォルトでは 'T' です) は 1 文字のセパレータで、結果の文字列の日付と時刻の間に置かれます。例えば:

>>> import datetime as dt
>>> class TZ(dt.tzinfo):
...     """任意の固定オフセット -06:39 を持つタイムゾーン。"""
...     def utcoffset(self, when):
...         return dt.timedelta(hours=-6, minutes=-39)
...
>>> dt.datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
>>> dt.datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat()
'2009-11-27T00:00:00.000100-06:39'

オプション引数 timespec は、含める追加の時間の要素の数を指定します(デフォルトでは 'auto' です)。以下の内一つを指定してください。

  • 'auto': microsecond が0である場合 'seconds' と等しく、そうでない場合は 'microseconds' と等しくなります。

  • 'hours': hour を2桁の HH 書式で含めます。

  • 'minutes': hour および minute を HH:MM の書式で含めます。

  • 'seconds': hour 、 minute 、 second を HH:MM:SS の書式で含めます。

  • 'milliseconds': 時刻全体を含めますが、秒の小数部分はミリ秒単位で切り捨てます。 HH:MM:SS.sss 形式になります。

  • 'microseconds': 全ての時刻を HH:MM:SS.ffffff の書式で含めます。

注釈

除外された要素は丸め込みではなく、切り捨てされます。

不正な timespec 引数には ValueError があげられます:

>>> import datetime as dt
>>> dt.datetime.now().isoformat(timespec='minutes')
'2002-12-25T00:00'
>>> my_datetime = dt.datetime(2015, 1, 1, 12, 30, 59, 0)
>>> my_datetime.isoformat(timespec='microseconds')
'2015-01-01T12:30:59.000000'

バージョン 3.6 で変更: timespec パラメータを追加しました.

datetime.__str__()

datetime インスタンス d について、str(d) は d.isoformat(' ') と等価です。

datetime.ctime()

日付および時刻を表す文字列を返します:

>>> import datetime as dt
>>> dt.datetime(2002, 12, 4, 20, 30, 40).ctime()
'Wed Dec  4 20:30:40 2002'

出力文字列は入力が aware であれ naive であれ、タイムゾーン情報を含み ません。

d.ctime() は次の式と等価です:

time.ctime(time.mktime(d.timetuple()))

これが等価になるのは、 (time.ctime() に呼び出され、 datetime.ctime() に呼び出されない) ネイティブの C 関数 ctime() が C 標準に準拠しているプラットフォーム上でです。

datetime.strftime(format)

明示的な書式文字列で制御された、日付および時刻を表現する文字列を返します。strftime() と strptime() の動作 および datetime.isoformat() も参照してください。

datetime.__format__(format)

datetime.strftime() と等価です。 これにより、 フォーマット済み文字列リテラル の中や str.format() を使っているときに datetime オブジェクトの書式文字列を指定できます。 strftime() と strptime() の動作 および datetime.isoformat() も参照してください。

使用例: datetime

datetime オブジェクトを使う例:

>>> import datetime as dt

>>> # datetime.combine() の使用
>>> d = dt.date(2005, 7, 14)
>>> t = dt.time(12, 30)
>>> dt.datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)

>>> # datetime.now() の使用
>>> dt.datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> dt.datetime.now(dt.timezone.utc)
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)

>>> # datetime.strptime() の使用
>>> my_datetime = dt.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> my_datetime
datetime.datetime(2006, 11, 21, 16, 30)

>>> # datetime.timetuple() で全属性のタプルを取得する
>>> tt = my_datetime.timetuple()
>>> for it in tt:
...     print(it)
...
2006    # 年
11      # 月
21      # 日
16      # 時
30      # 分
0       # 秒
1       # 曜日 (0 = 月曜日)
325     # 1 月 1 日から数えた日数
-1      # dst - メソッド tzinfo.dst() が None を返した

>>> # ISO 形式の日付
>>> ic = my_datetime.isocalendar()
>>> for it in ic:
...     print(it)
...
2006    # ISO の年
47      # ISO の週
2       # ISO の曜日

>>> # datetime の書式設定
>>> my_datetime.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(my_datetime, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

下にある例では、1945年までは +4 UTC 、それ以降は +4:30 UTC を使用しているアフガニスタンのカブールのタイムゾーン情報を表現する tzinfo のサブクラスを定義しています:

import datetime as dt

class KabulTz(dt.tzinfo):
    # Kabul used +4 until 1945, when they moved to +4:30
    UTC_MOVE_DATE = dt.datetime(1944, 12, 31, 20, tzinfo=dt.timezone.utc)

    def utcoffset(self, when):
        if when.year < 1945:
            return dt.timedelta(hours=4)
        elif (1945, 1, 1, 0, 0) <= when.timetuple()[:5] < (1945, 1, 1, 0, 30):
            # An ambiguous ("imaginary") half-hour range representing
            # a 'fold' in time due to the shift from +4 to +4:30.
            # If when falls in the imaginary range, use fold to decide how
            # to resolve. See PEP 495.
            return dt.timedelta(hours=4, minutes=(30 if when.fold else 0))
        else:
            return dt.timedelta(hours=4, minutes=30)

    def fromutc(self, when):
        # Follow same validations as in datetime.tzinfo
        if not isinstance(when, dt.datetime):
            raise TypeError("fromutc() requires a datetime argument")
        if when.tzinfo is not self:
            raise ValueError("when.tzinfo is not self")

        # A custom implementation is required for fromutc as
        # the input to this function is a datetime with utc values
        # but with a tzinfo set to self.
        # See datetime.astimezone or fromtimestamp.
        if when.replace(tzinfo=dt.timezone.utc) >= self.UTC_MOVE_DATE:
            return when + dt.timedelta(hours=4, minutes=30)
        else:
            return when + dt.timedelta(hours=4)

    def dst(self, when):
        # Kabul does not observe daylight saving time.
        return dt.timedelta(0)

    def tzname(self, when):
        if when >= self.UTC_MOVE_DATE:
            return "+04:30"
        return "+04"

上に出てきた KabulTz の使い方:

>>> tz1 = KabulTz()

>>> # 変更前の日時
>>> dt1 = dt.datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00

>>> # 変更後の日時
>>> dt2 = dt.datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> print(dt2.utcoffset())
4:30:00

>>> # 日時を別のタイムゾーンに変換する
>>> dt3 = dt2.astimezone(dt.timezone.utc)
>>> dt3
datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc)
>>> dt2
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz())
>>> dt2 == dt3
True

time オブジェクト

time オブジェクトは (ローカルの) 日中時刻を表現します。 この時刻表現は特定の日の影響を受けず、 tzinfo オブジェクトを介した修正の対象となります。

class datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

全ての引数はオプションです。 tzinfo は None または tzinfo クラスのサブクラスのインスタンスにすることができます。残りの引数は整数で、以下のような範囲に入らなければなりません:

  • 0 <= hour < 24,

  • 0 <= minute < 60,

  • 0 <= second < 60,

  • 0 <= microsecond < 1000000,

  • fold in [0, 1].

引数がこれらの範囲外にある場合、 ValueError が送出されます。 tzinfo のデフォルト値が None である以外のデフォルト値は0です。

以下にクラス属性を示します:

time.min

表現できる最も古い time で、 time(0, 0, 0, 0) です。

time.max

表現できる最も新しい time で、 time(23, 59, 59, 999999) です。

time.resolution

等しくない time オブジェクト間の最小の差で、 timedelta(microseconds=1) ですが, time オブジェクト間の四則演算はサポートされていないので注意してください。

インスタンスの属性 (読み出しのみ):

time.hour

in range(24) を満たします。

time.minute

in range(60) を満たします。

time.second

in range(60) を満たします。

time.microsecond

in range(1000000) を満たします。

time.tzinfo

time コンストラクタに tzinfo 引数として与えられたオブジェクトになり、何も渡されなかった場合には None になります。

time.fold

[0, 1] のどちらかです。 繰り返し期間中の実時間の曖昧さ除去に使われます。 (繰り返し期間は、夏時間の終わりに時計が巻き戻るときや、現在のゾーンの UTC オフセットが政治的な理由で減少するときに発生します。) 0または1という値は、同じ実時間で表現される 2 つの時刻のうちのそれぞれ早い方または遅い方を表します。

Added in version 3.6.

time オブジェクトは等価比較と順序比較をサポートします。 a が時刻として b より前を表す場合、a は b より小さいとみなされます。

naive な time オブジェクトと aware なものが等しくなることはありません。 naive な time オブジェクトと aware なものの順序比較は、TypeError を送出します。

比較対象が両方とも aware であり、同じ tzinfo 属性を持つ場合、 tzinfo と fold 属性は無視され時間だけで比較が行われます。比較対象が両方とも aware であり、異なる tzinfo 属性を持つ場合、まず最初に (self.utcoffset() で取得できる) それぞれの UTC オフセットを引く調整が行われます。

バージョン 3.3 で変更: aware な インスタンスと naive な time インスタンスの等価比較では TypeError は送出されません。

ブール値の文脈では、 time オブジェクトは常に真とみなされます。

バージョン 3.5 で変更: Python 3.5 より前では、time オブジェクトが UTC の午前 0 時を表す場合、偽とみなされていました。 この動作は分かりにくく誤りを招きやすいと判断され、Python 3.5 で削除されました。 詳細は bpo-13936 を参照してください。

その他のコンストラクタ:

classmethod time.fromisoformat(time_string)

以下の例外を除く、有効な ISO 8601 フォーマットで与えられた time_string に対応する time を返します :

  1. 小数の秒があるタイムゾーンオフセット。

  2. 日付と時刻の区別が曖昧になる可能性がある場合に通常必要となる、先頭の T は必須ではありません。

  3. 秒の小数部分の桁数は任意です (6 桁を超える部分は切り捨てられます)。

  4. 少数の時と分はサポートされていません。

例:

>>> import datetime as dt
>>> dt.time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('T04:23:01')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('T042301')
datetime.time(4, 23, 1)
>>> dt.time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> dt.time.fromisoformat('04:23:01,000384')
datetime.time(4, 23, 1, 384)
>>> dt.time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
>>> dt.time.fromisoformat('04:23:01Z')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
>>> dt.time.fromisoformat('04:23:01+00:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)

Added in version 3.7.

バージョン 3.11 で変更: 以前は、このメソッドは time.isoformat() が出力できる形式だけをサポートしていました。

classmethod time.strptime(date_string, format)

format に従って date_string を解析し、対応する time を返します。

format がマイクロ秒やタイムゾーン情報を含まない場合は、以下と等価です:

time(*(time.strptime(date_string, format)[3:6]))

date_string と format を time.strptime() で解析できない場合、またはその返り値が時刻タプルでない場合、ValueError を送出します。 strftime() と strptime() の動作 と time.fromisoformat() も参照してください。

Added in version 3.14.

インスタンスメソッド:

time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, *, fold=0)

指定したパラメータだけを更新し、それ以外は同じ値を持つ新しい time を返します。 tzinfo=None を指定すると、時刻のデータを変換せずに、aware な time から naive な time を作成できます。

time オブジェクトは汎用的な関数 copy.replace() にもサポートされています。

バージョン 3.6 で変更: fold パラメータが追加されました。

time.isoformat(timespec='auto')

時刻を ISO 8601 書式で表した次の文字列のうち1つを返します:

オプション引数 timespec は、含める追加の時間の要素の数を指定します(デフォルトでは 'auto' です)。以下の内一つを指定してください。

  • 'auto': microsecond が0である場合 'seconds' と等しく、そうでない場合は 'microseconds' と等しくなります。

  • 'hours': hour を2桁の HH 書式で含めます。

  • 'minutes': hour および minute を HH:MM の書式で含めます。

  • 'seconds': hour 、 minute 、 second を HH:MM:SS の書式で含めます。

  • 'milliseconds': 時刻全体を含めますが、秒の小数部分はミリ秒単位で切り捨てます。 HH:MM:SS.sss 形式になります。

  • 'microseconds': 全ての時刻を HH:MM:SS.ffffff の書式で含めます。

注釈

除外された要素は丸め込みではなく、切り捨てされます。

不正な timespec 引数には ValueError があげられます。

以下はプログラム例です:

>>> import datetime as dt
>>> dt.time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
'12:34'
>>> my_time = dt.time(hour=12, minute=34, second=56, microsecond=0)
>>> my_time.isoformat(timespec='microseconds')
'12:34:56.000000'
>>> my_time.isoformat(timespec='auto')
'12:34:56'

バージョン 3.6 で変更: timespec パラメータを追加しました.

time.__str__()

時刻 t について、str(t) は t.isoformat() と等価です。

time.strftime(format)

明示的な書式文字列で制御された、時刻を表現する文字列を返します。strftime() と strptime() の動作 および time.isoformat() も参照してください。

time.__format__(format)

time.strftime() と等価です。 これにより、 フォーマット済み文字列リテラル の中や str.format() を使っているときに time オブジェクトの書式文字列を指定できます。 strftime() と strptime() の動作 および time.isoformat() も参照してください。

time.utcoffset()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.utcoffset(None) を返します。 後者の式が None あるいは 1 日未満の大きさを持つ timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

time.dst()

tzinfo が None の場合 None を返し、そうでない場合には self.tzinfo.dst(None) を返します。 後者の式が None もしくは、1 日未満の大きさを持つ timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

バージョン 3.7 で変更: DST オフセットが分単位でなければならない制限が無くなりました。

time.tzname()

tzinfo が None の場合 None を返し、そうでない場合には self.tzinfo.tzname(None) を返します。 後者の式が None か文字列オブジェクトのいずれかを返さない場合には例外を送出します。

使用例: time

time オブジェクトを使う例:

>>> import datetime as dt
>>> class TZ1(dt.tzinfo):
...     def utcoffset(self, when):
...         return dt.timedelta(hours=1)
...     def dst(self, when):
...         return dt.timedelta(0)
...     def tzname(self, when):
...         return "+01:00"
...     def  __repr__(self):
...         return f"{self.__class__.__name__}()"
...
>>> t = dt.time(12, 10, 30, tzinfo=TZ1())
>>> t
datetime.time(12, 10, 30, tzinfo=TZ1())
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'+01:00'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 +01:00'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'

tzinfo オブジェクト

class datetime.tzinfo

これは abstract base class であり、直接インスタンス化すべきではないクラスです。 特定のタイムゾーンについての情報を保持するには、tzinfo のサブクラスを定義してください。

tzinfo (の具象サブクラス) のインスタンスは、datetime と time オブジェクトのコンストラクタに渡せます。 これらの日時オブジェクトは自分の属性をローカル時刻とみなします。 tzinfo オブジェクトは、渡された日付または時刻オブジェクトに応じて、ローカル時刻の UTC からのオフセット、タイムゾーン名、DST オフセットを返すメソッドをサポートします。

具象サブクラスを派生させ、少なくとも使用する datetime のメソッドが必要とする標準の tzinfo メソッドを実装する必要があります。 datetime モジュールは、tzinfo の単純な具象サブクラス timezone を提供します。 これは UTC 自体や北米の EST と EDT など、UTC からのオフセットが固定されたタイムゾーンを表現できます。

pickle 化についての特殊な要求事項: tzinfo のサブクラスは引数なしで呼び出すことのできる __init__() メソッドを持たなければなりません。そうでなければ、 pickle 化することはできますがおそらく unpickle 化することはできないでしょう。これは技術的な側面からの要求であり、将来緩和されるかもしれません。

tzinfo の具体的なサブクラスでは、以下のメソッドを実装する必要があります。厳密にどのメソッドが必要なのかは、 aware な datetime オブジェクトがこのサブクラスのインスタンスをどのように使うかに依存します。不確かならば、単に全てを実装してください。

tzinfo.utcoffset(dt)

ローカル時間の UTC からのオフセットを、 UTC から東向きを正とした timedelta オブジェクトで返します。ローカル時間が UTC の西側にある場合、この値は負になります。

このメソッドは UTC からのオフセットの 総計 を表しています。例えば、 tzinfo オブジェクトがタイムゾーンと DST 修正の両方を表現する場合、 utcoffset() はそれらの合計を返さなければなりません。 UTC オフセットが未知である場合、 None を返します。 そうでない場合には、返される値は -timedelta(hours=24) から timedelta(hours=24) までの timedelta 境界を含まないオブジェクトでなければなりません (オフセットの大きさは 1 日より短くなければなりません)。 ほとんどの utcoffset() 実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:

return CONSTANT                 # 固定オフセットのクラス
return CONSTANT + self.dst(dt)  # 夏時間を考慮するクラス

utcoffset() が None を返さない場合、 dst() も None を返してはなりません。

utcoffset() のデフォルトの実装は NotImplementedError を送出します。

バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

tzinfo.dst(dt)

夏時間 (DST) 修正を、 timedelta オブジェクトで返します。 DST 情報が未知の場合、 None が返されます。

DST が適用されない場合は timedelta(0) を返します。 適用される場合は、調整量を timedelta オブジェクトで返します (詳細は utcoffset() を参照してください)。 DST の調整量は utcoffset() が返す UTC オフセットにすでに加算されているため、DST 情報を個別に取得したい場合を除き、dst() を呼び出す必要はありません。 例えば、datetime.timetuple() は tzinfo 属性の dst() メソッドを呼び出して、tm_isdst フラグに設定する値を決定します。 また tzinfo.fromutc() は dst() を呼び出し、タイムゾーンをまたぐ際の DST の変化を考慮します。

標準および夏時間の両方をモデル化している tzinfo サブクラスのインスタンス tz は以下の式:

tz.utcoffset(dt) - tz.dst(dt)

が dt.tzinfo == tz を満たすすべての datetime dt に対して同じ結果を返す、という意味で一貫している必要があります。 適切な tzinfo サブクラスでは、この式はタイムゾーンの「標準オフセット」を返します。 これは日時には依存せず、地理的な位置のみに依存するべきです。 datetime.astimezone() の実装はこの性質に依存しますが、違反を検出できないため、保証するのはプログラマの責任です。 tzinfo サブクラスがこの性質を保証できない場合でも、tzinfo.fromutc() のデフォルト実装をオーバーライドすれば、astimezone() と正しく動作できる場合があります。

ほとんどの dst() 実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:

import datetime as dt

def dst(self, when):
    # 固定オフセットのクラス: DST を考慮しない
    return dt.timedelta(0)

もしくは:

import datetime as dt

def dst(self, when):
    # 入力の when.year に基づいて、そのタイムゾーンの DST の
    # 開始時刻と終了時刻を標準のローカル時刻で表し、
    # dston と dstoff に設定するコード。

    if dston <= when.replace(tzinfo=None) < dstoff:
        return dt.timedelta(hours=1)
    else:
        return dt.timedelta(0)

デフォルトの dst() 実装は NotImplementedError を送出します。

バージョン 3.7 で変更: DST オフセットが分単位でなければならない制限が無くなりました。

tzinfo.tzname(dt)

datetime オブジェクト dt に対応するタイムゾーン名を文字列として返します。 datetime モジュールは名前の文字列について何も定義しておらず、特定の意味を持つ必要もありません。 例えば、"GMT"、"UTC"、"-500"、"-5:00"、"EDT"、"US/Eastern"、"America/New York" はすべて有効な返り値です。 名前の文字列が不明な場合は None を返します。 固定文字列ではなくメソッドになっている主な理由は、一部の tzinfo サブクラスが、渡された dt の具体的な値に応じて異なる名前を返したい場合があるためです。 特に、tzinfo クラスが夏時間を考慮する場合が当てはまります。

デフォルトの tzname() 実装は NotImplementedError を送出します。

これらのメソッドは、datetime または time オブジェクトの同名のメソッドに応じて呼び出されます。 datetime オブジェクトは引数として自身を渡し、time オブジェクトは None を渡します。 したがって、tzinfo サブクラスのメソッドは、dt 引数として None または datetime クラスのオブジェクトを受け付けられるようにする必要があります。

None が渡された場合、最良の応答方法を決めるのはクラス設計者です。 例えば、時刻オブジェクトが tzinfo プロトコルに関与しないことを表したい場合は、None を返すのが適切です。 標準オフセットを調べる方法は他に定められていないため、utcoffset(None) が標準の UTC オフセットを返す方が便利な場合もあります。

datetime のメソッドに応じて datetime オブジェクトが渡される場合、dt.tzinfo は self と同じオブジェクトです。 ユーザーコードが tzinfo メソッドを直接呼び出さない限り、tzinfo メソッドはこの性質に依存できます。 これは、tzinfo メソッドが dt をローカル時刻と解釈し、他のタイムゾーンのオブジェクトを気にする必要がないようにするためです。

サブクラスでオーバーライドすると良い、もう 1 つの tzinfo のメソッドがあります:

tzinfo.fromutc(dt)

デフォルトの datetime.astimezone() 実装から呼び出されます。 その場合、dt.tzinfo は self であり、dt の日付と時刻は UTC を表すものとして解釈します。 fromutc() は日付と時刻を調整し、同じ時点を self のローカル時刻で表す datetime を返すためのメソッドです。

ほとんどの tzinfo サブクラスではデフォルトの fromutc() 実装を問題なく継承できます。デフォルトの実装は、固定オフセットのタイムゾーンや、標準時と夏時間の両方について記述しているタイムゾーン、そして DST 移行時刻が年によって異なる場合でさえ、扱えるくらい強力なものです。デフォルトの fromutc() 実装が全ての場合に対して正しく扱うことができないような例は、標準時の (UTCからの) オフセットが引数として渡された特定の日や時刻に依存するもので、これは政治的な理由によって起きることがあります。デフォルトの astimezone() や fromutc() の実装は、結果が標準時オフセットの変化にまたがる何時間かの中にある場合、期待通りの結果を生成しないかもしれません。

エラーの場合のためのコードを除き、デフォルトの fromutc() の実装は以下のように動作します:

import datetime as dt

def fromutc(self, when):
    # when.tzinfo is not self の場合は ValueError を送出する
    dtoff = when.utcoffset()
    dtdst = when.dst()
    # dtoff is None または dtdst is None の場合は ValueError を送出する
    delta = dtoff - dtdst  # これは self の標準オフセット
    if delta:
        when += delta   # 標準のローカル時刻に変換する
        dtdst = when.dst()
        # dtdst is None の場合は ValueError を送出する
    if dtdst:
        return when + dtdst
    else:
        return when

次の tzinfo_examples.py ファイルには、 tzinfo クラスの例がいくつか載っています:

import datetime as dt

# プラットフォームが認識するローカル時刻を表すクラス。
# (UTC オフセットや DST の規則が過去に変更された
# タイムゾーンでは、過去の時刻に対して
# 誤った値になる場合がある。)
import time

ZERO = dt.timedelta(0)
HOUR = dt.timedelta(hours=1)
SECOND = dt.timedelta(seconds=1)

STDOFFSET = dt.timedelta(seconds=-time.timezone)
if time.daylight:
    DSTOFFSET = dt.timedelta(seconds=-time.altzone)
else:
    DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET


class LocalTimezone(dt.tzinfo):

    def fromutc(self, when):
        assert when.tzinfo is self
        stamp = (when - dt.datetime(1970, 1, 1, tzinfo=self)) // SECOND
        args = time.localtime(stamp)[:6]
        dst_diff = DSTDIFF // SECOND
        # 折り返しを検出する
        fold = (args == time.localtime(stamp - dst_diff))
        return dt.datetime(*args, microsecond=when.microsecond,
                           tzinfo=self, fold=fold)

    def utcoffset(self, when):
        if self._isdst(when):
            return DSTOFFSET
        else:
            return STDOFFSET

    def dst(self, when):
        if self._isdst(when):
            return DSTDIFF
        else:
            return ZERO

    def tzname(self, when):
        return time.tzname[self._isdst(when)]

    def _isdst(self, when):
        tt = (when.year, when.month, when.day,
              when.hour, when.minute, when.second,
              when.weekday(), 0, 0)
        stamp = time.mktime(tt)
        tt = time.localtime(stamp)
        return tt.tm_isdst > 0


Local = LocalTimezone()


# 米国の主要なタイムゾーンについて、現在の DST 規則を完全に実装する。

def first_sunday_on_or_after(when):
    days_to_go = 6 - when.weekday()
    if days_to_go:
        when += dt.timedelta(days_to_go)
    return when


# 米国の DST 規則
#
# これは米国の DST の開始時刻と終了時刻について簡略化した
# (つまり一部のケースでは誤った) 規則である。完全で最新の DST 規則と
# タイムゾーン定義は Olson Database を参照 (または pytz を試すこと):
# http://www.twinsun.com/tz/tz-link.htm
# https://sourceforge.net/projects/pytz/ (最新でない場合がある)
#
# 米国では 2007 年以降、DST は 3 月の第 2 日曜日、
# つまり 3 月 8 日以降の最初の日曜日の午前 2 時 (標準時) に始まる。
DSTSTART_2007 = dt.datetime(1, 3, 8, 2)
# 11 月の第 1 日曜日の午前 2 時 (夏時間) に終わる。
DSTEND_2007 = dt.datetime(1, 11, 1, 2)
# 1987 年から 2006 年まで、DST は 4 月の第 1 日曜日の午前 2 時 (標準時)
# に始まり、10 月の最後の日曜日、つまり 10 月 25 日以降の
# 最初の日曜日の午前 2 時 (夏時間) に終わっていた。
DSTSTART_1987_2006 = dt.datetime(1, 4, 1, 2)
DSTEND_1987_2006 = dt.datetime(1, 10, 25, 2)
# 1967 年から 1986 年まで、DST は 4 月の最後の日曜日 (4 月 24 日以降の
# 日曜日) の午前 2 時 (標準時) に始まり、10 月の最後の日曜日、
# つまり 10 月 25 日以降の最初の日曜日の
# 午前 2 時 (夏時間) に終わっていた。
DSTSTART_1967_1986 = dt.datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006


def us_dst_range(year):
    # 米国の DST の開始時刻と終了時刻を求める。1967 年より前の年は
    # DST がないため start = end を返す。
    if 2006 < year:
        dststart, dstend = DSTSTART_2007, DSTEND_2007
    elif 1986 < year < 2007:
        dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
    elif 1966 < year < 1987:
        dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
    else:
        return (dt.datetime(year, 1, 1), ) * 2

    start = first_sunday_on_or_after(dststart.replace(year=year))
    end = first_sunday_on_or_after(dstend.replace(year=year))
    return start, end


class USTimeZone(dt.tzinfo):

    def __init__(self, hours, reprname, stdname, dstname):
        self.stdoffset = dt.timedelta(hours=hours)
        self.reprname = reprname
        self.stdname = stdname
        self.dstname = dstname

    def __repr__(self):
        return self.reprname

    def tzname(self, when):
        if self.dst(when):
            return self.dstname
        else:
            return self.stdname

    def utcoffset(self, when):
        return self.stdoffset + self.dst(when)

    def dst(self, when):
        if when is None or when.tzinfo is None:
            # ここでは、一方または両方の場合に例外を送出するのが妥当かもしれない。
            # どのように扱いたいかによる。デフォルトの fromutc() の実装
            # (デフォルトの astimezone() の実装から呼び出される) は、
            # when.tzinfo is self である datetime を渡す。
            return ZERO
        assert when.tzinfo is self
        start, end = us_dst_range(when.year)
        # naive と aware のオブジェクトは比較できないため、先に when から
        # タイムゾーンを取り除く。
        when = when.replace(tzinfo=None)
        if start + HOUR <= when < end - HOUR:
            # DST が適用されている。
            return HOUR
        if end - HOUR <= when < end:
            # 折り返し (曖昧な 1 時間): when.fold で曖昧さを解消する。
            return ZERO if when.fold else HOUR
        if start <= when < start + HOUR:
            # 欠落 (存在しない 1 時間): 折り返しの規則を逆にする。
            return HOUR if when.fold else ZERO
        # DST は適用されていない。
        return ZERO

    def fromutc(self, when):
        assert when.tzinfo is self
        start, end = us_dst_range(when.year)
        start = start.replace(tzinfo=self)
        end = end.replace(tzinfo=self)
        std_time = when + self.stdoffset
        dst_time = std_time + HOUR
        if end <= dst_time < end + HOUR:
            # 繰り返される 1 時間
            return std_time.replace(fold=1)
        if std_time < start or dst_time >= end:
            # 標準時
            return std_time
        if start <= std_time < end - HOUR:
            # 夏時間
            return dst_time


Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
Central  = USTimeZone(-6, "Central",  "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")

標準時および夏時間の両方を記述している tzinfo のサブクラスでは、夏時間の移行のときに、回避不能の難解な問題が年に 2 度あるので注意してください。 具体的な例として、東部アメリカ時刻 (US Eastern, UTC -0500) を考えます。 EDT は 3 月の第二日曜日の 1:59 (EST) の 1 分後に開始し、11 月の最初の日曜日の 1:59 (EDT) の 1 分後に終了します。

  UTC   3:MM  4:MM  5:MM  6:MM  7:MM  8:MM
  EST  22:MM 23:MM  0:MM  1:MM  2:MM  3:MM
  EDT  23:MM  0:MM  1:MM  2:MM  3:MM  4:MM

start  22:MM 23:MM  0:MM  1:MM  3:MM  4:MM

  end  23:MM  0:MM  1:MM  1:MM  2:MM  3:MM

DSTの開始 ("start" ライン) で、ローカルの実時間は 1:59 から 3:00 に飛びます。 この日には、 2:MM という形式の実時間は意味をなさないので、 DST が始まった日に astimezone(Eastern) は hour == 2 となる結果を返すことはありません。 例として、 2016 年の春方向の移行では、次のような結果になります:

>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = dt.datetime(2016, 3, 13, 5, tzinfo=dt.timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname())
...
05:00:00 UTC = 00:00:00 EST
06:00:00 UTC = 01:00:00 EST
07:00:00 UTC = 03:00:00 EDT
08:00:00 UTC = 04:00:00 EDT

DST が終了 ("end" ライン) で、更なる問題が潜んでいます: ローカルの実時間で、曖昧さ無しに時を綴れない 1 時間が存在します: それは夏時間の最後の 1 時間です。 東部では、夏時間が終了する日の UTC での 5:MM 形式の時間がそれです。 ローカルの実時間は (夏時間の) 1:59 から (標準時の) 1:00 に再び巻き戻されます。 ローカルの時刻における 1:MM は曖昧です。 そして astimezone() は 2 つの隣り合う UTC 時間を同じローカルの時間に対応付けて、ローカルの時計の振る舞いを真似ます。 東部の例では、 5:MM および 6:MM という形式の UTC 時刻は両方とも東部時刻に変換された際に 1:MM に対応付けられますが、それ以前の時間は fold 属性を 0 にし、以降の時間では 1 にします。例えば、 2016 年での秋方向の移行では、次のような結果になります:

>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = dt.datetime(2016, 11, 6, 4, tzinfo=dt.timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0

fold 属性が異なるだけの datetime インスタンスは比較において等しいとみなされることに注意してください。

時計が示す時刻の曖昧さを許容できないアプリケーションは、fold 属性の値を明示的に調べるか、標準時と夏時間を組み合わせた tzinfo サブクラスの使用を避けるべきです。 timezone や、その他の固定オフセットの tzinfo サブクラス (EST だけを表すクラス (固定オフセット -5 時間) や、EDT だけを表すクラス (固定オフセット -4 時間) など) を使用する場合、曖昧さはありません。

参考

zoneinfo

datetime モジュールには (UTC からの任意の固定オフセットを扱う) 基本的な timezone クラスと、(UTC timezone のインスタンスである) timezone.utc 属性があります。

zoneinfo は Python に IANA タイムゾーンデータベース (オルソンデータベースとしても知られています) を導入するもので、これを使うことが推奨されています。

IANA タイムゾーンデータベース

(しばしば tz、tzdata や zoneinfo と呼ばれる) タイムゾーンデータベースはコードとデータを保持しており、それらは地球全体にわたる多くの代表的な場所のローカル時刻の履歴を表しています。政治団体によるタイムゾーンの境界、UTC オフセット、夏時間のルールの変更を反映するため、定期的にデータベースが更新されます。

timezone オブジェクト

timezone クラスは tzinfo のサブクラスで、各インスタンスは UTC からの固定されたオフセットで定義されたタイムゾーンを表しています。

このクラスのオブジェクトは、一年のうち異なる日に異なるオフセットが使われていたり、常用時 (civil time) に歴史的な変化が起きた場所のタイムゾーン情報を表すのには使えないので注意してください。

class datetime.timezone(offset[, name])

ローカル時刻と UTC の差分を表す timedelta オブジェクトを offset 引数に指定しなくてはいけません。これは -timedelta(hours=24) から timedelta(hours=24) までの両端を含まない範囲に収まっていなくてはなりません。そうでない場合 ValueError が送出されます。

name 引数は必須ではありません。もし指定された場合、その値は datetime.tzname() メソッドの返り値として使われる文字列でなければなりません。

Added in version 3.2.

バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

timezone.utcoffset(dt)

timezone インスタンスが構築されたときに指定された固定値を返します。

dt 引数は無視されます。 返り値は、ローカル時刻と UTC の差分に等しい timedelta インスタンスです。

バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

timezone.tzname(dt)

timezone インスタンスが構築されたときに指定された固定値を返します。

name が構築時に与えられなかった場合、 tzname(dt) によって返される name は以下の様に offset の値から生成されます。 offset が timedelta(0) であった場合、 name は "UTC"になります。 それ以外の場合、 'UTC±HH:MM' という書式の文字列になり、± は offset の符号を、HH と MM はそれぞれ二桁の offset.hours と offset.minutes を表現します。

バージョン 3.6 で変更: offset=timedelta(0) によって生成される名前はプレーンな 'UTC' であり 'UTC+00:00' ではありません。

timezone.dst(dt)

常に None を返します。

timezone.fromutc(dt)

dt + offset を返します。 dt 引数は tzinfo が self になっている aware な datetime インスタンスでなければなりません。

以下にクラス属性を示します:

timezone.utc

UTC タイムゾーン timezone(timedelta(0)) です。

strftime() と strptime() の動作

date, datetime, time オブジェクトは全て strftime(format) メソッドをサポートし、時刻を表現する文字列を明示的な書式文字列で統制して作成しています。

逆に、クラスメソッド date.strptime()、datetime.strptime()、time.strptime() は、時刻を表す文字列と対応する書式文字列からオブジェクトを作成します。

下の表は strftime() と strptime() との高レベルの対比を表しています。

strftime

strptime

使用法

オブジェクトを与えられた書式に従って文字列に変換する

対応する書式を指定して文字列を解析し、オブジェクトに変換する

メソッドの種類

インスタンスメソッド

クラスメソッド

シグネチャ

strftime(format)

strptime(date_string, format)

strftime() と strptime() の書式コード

これらのメソッドは、日付の解析と書式設定に使用できる書式コードを受け付けます。

>>> import datetime as dt
>>> dt.datetime.strptime('31/01/22 23:59:59.999999',
...                      '%d/%m/%y %H:%M:%S.%f')
datetime.datetime(2022, 1, 31, 23, 59, 59, 999999)
>>> _.strftime('%a %d %b %Y, %I:%M%p')
'Mon 31 Jan 2022, 11:59PM'

以下は、2011 年の C 標準で必須とされるすべての書式コードの一覧であり、サポートされるすべてのプラットフォームで動作します。

ディレクティブ

意味

使用例

注釈

%a

ロケールの曜日名を短縮形で表示します。

Sun, Mon, ..., Sat (en_US);
So, Mo, ..., Sa (de_DE)

(1)

%A

ロケールの曜日名を表示します。

Sunday, Monday, ..., Saturday (en_US);
Sonntag, Montag, ..., Samstag (de_DE)

(1)

%b

ロケールの月名を短縮形で表示します。

Jan, Feb, ..., Dec (en_US);
Jan, Feb, ..., Dez (de_DE)

(1)

%B

ロケールの月名を表示します。

January, February, ..., December (en_US);
Januar, Februar, ..., Dezember (de_DE)

(1)

%c

ロケールの日時を適切な形式で表します。

Tue Aug 16 21:30:00 1988 (en_US);
Di 16 Aug 21:30:00 1988 (de_DE)

(1)

%C

年を 100 で割り、小数部分を切り捨てた整数をゼロ埋めした 10 進数。

01, 02, ..., 99

(0)

%d

0埋めした10進数で表記した月中の日にち。

01, 02, ..., 31

(9), (10)

%D

%m/%d/%y と等価。

11/28/25

(9)

%e

月内の日を空白埋めした 10 進数。

␣1, ␣2, ..., 31

(10)

%F

ISO 8601 形式の %Y-%m-%d と等価。

2025-10-11, 1001-12-30

%g

ISO 週 (%V) の大半が属する年を表す ISO 8601 年の下 2 桁。

00, 01, ..., 99

(0)

%G

ISO week(%V)の内過半数を含む西暦表記の ISO 8601 year です。

0001, 0002, ..., 2013, 2014, ..., 9998, 9999

(8)

%h

%b と等価。

%b を参照。

(0)

%H

0埋めした10進数で表記した時 (24時間表記)。

00, 01, ..., 23

(9)

%I

0埋めした10進数で表記した時 (12時間表記)。

01, 02, ..., 12

(9)

%j

0埋めした10進数で表記した年中の日にち。

001, 002, ..., 366

(9)

%m

0埋めした10進数で表記した月。

01, 02, ..., 12

(9)

%M

0埋めした10進数で表記した分。

00, 01, ..., 59

(9)

%n

改行文字 ('\n')。 strptime() では 0 個以上の空白文字。

\n

%p

ロケールの AM もしくは PM と等価な文字列になります。

AM, PM (en_US);
am, pm (de_DE)

(1), (3)

%r

ロケールの 12 時間制の時刻。

12:00:00 AM

(1), (0)

%R

%H:%M と等価。

10:01

%S

0埋めした10進数で表記した秒。

00, 01, ..., 59

(4), (9)

%t

タブ文字 ('\t')。 strptime() では 0 個以上の空白文字。

\t

%T

ISO 8601 の時刻形式で、%H:%M:%S と等価。

10:01:59

%u

1 を月曜日を表す 10進数表記の ISO 8601 weekday です。

1, 2, ..., 7

%U

0埋めした10進数で表記した年中の週番号 (週の始まりは日曜日とする)。新年の最初の日曜日に先立つ日は 0週に属するとします。

00, 01, ..., 53

(7), (9)

%V

週で最初の月曜日を始めとする ISO 8601 week です。Week 01 は 1月4日を含みます。

01, 02, ..., 53

(8), (9)

%w

曜日を10進表記した文字列を表示します。0 が日曜日で、6 が土曜日を表します。

0, 1, ..., 6

%W

0埋めした10進数で表記した年中の週番号 (週の始まりは月曜日とする)。新年の最初の月曜日に先立つ日は 0週に属するとします。

00, 01, ..., 53

(7), (9)

%x

ロケールの日付を適切な形式で表します。

08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)

(1)

%X

ロケールの時間を適切な形式で表します。

21:30:00 (en_US);
21:30:00 (de_DE)

(1)

%y

0埋めした10進数で表記した世紀無しの年。

00, 01, ..., 99

(9)

%Y

西暦 ( 4桁) の 10 進表記を表します。

0001, 0002, ..., 2013, 2014, ..., 9998, 9999

(2)

%z

UTCオフセットを ±HHMM[SS[.ffffff]] の形式で表示します (オブジェクトがnaiveであれば空文字列)。

(空文字列), +0000, -0400, +1030, +063415, -030712.345216

(6)

%Z

タイムゾーンの名前を表示します (オブジェクトがnaiveであれば空文字列)。

(空文字列), UTC, GMT

(6)

%%

文字 '%' を表します。

%

ISO 8601 の年と週の指定子は、上記の年と週番号の指定子と交換可能ではありません。 不完全または曖昧な ISO 8601 指定子を指定して strptime() を呼び出すと、ValueError を送出します。

利便性のために、C11 標準で必須とされていない追加の指定子もいくつか含まれています。

ディレクティブ

意味

使用例

注釈

%f

10進数で表記したマイクロ秒 (6桁に0埋めされます)。

000000, 000001, ..., 999999

(5)

%:z

UTCオフセットを ±HH:MM[:SS[.ffffff]] の形式で表示します (オブジェクトがnaiveであれば空文字列)。

(空文字列), +00:00, -04:00, +10:30, +06:34:15, -03:07:12.345216

(6)

Python はプラットフォームの C ライブラリの strftime() 関数を呼び出していて、プラットフォームごとにその実装が異なるのはよくあることなので、サポートされる書式コード全体はプラットフォームごとに様々です。 手元のプラットフォームでサポートされているフォーマット記号全体を見るには、 strftime(3) のドキュメントを参照してください。 サポートされていないフォーマット指定子の扱いもプラットフォーム間で差異があります。

Added in version 3.6: %G, %u および %V が追加されました。

Added in version 3.12: strftime() に %:z が追加されました。

Added in version 3.15: strptime() に %D、%F、%n、%t、%:z が追加されました。

技術的な詳細

大雑把にいうと、 d.strftime(fmt) は time モジュールの time.strftime(fmt, d.timetuple()) のように動作します。ただし全てのオブジェクトが timetuple() メソッドをサポートしているわけではありません。

クラスメソッド datetime.strptime() と date.strptime() のデフォルト値は 1900-01-01T00:00:00.000 です。 書式文字列で指定されていない成分には、このデフォルト値が使われます。

注釈

区切り文字を含まない書式文字列は、解析時に曖昧になる場合があります。 例えば、%Y%m%d を使うと、文字列 2026111 は 2026-11-01 とも 2026-01-11 とも解析できます。 入力が意図どおりに解析されるよう、区切り文字を使用してください。

注釈

年を欠いた日付の一部を解析する際、datetime.strptime() と date.strptime() は 2 月 29 日に対して例外を送出します。 デフォルトの年である 1900 年がうるう年 ではない ためです。 日付の一部を表す文字列には、解析する前に必ずデフォルトのうるう年を追加してください。

注釈

strptime() の書式文字列に、%Y と %y の両方など、同じフィールドに対する指定子が複数含まれる場合でも、すべての指定子が入力に一致する必要がありますが、使用されるのは最後の指定子の値だけです。 例えば、%Y%y で 200099 を解析すると 1999 年になります。 %Y%Y のように同じ指定子を繰り返すとエラーになります。

>>> import datetime as dt
>>> value = "2/29"
>>> dt.datetime.strptime(value, "%m/%d")
Traceback (most recent call last):
...
ValueError: day 29 must be in range 1..28 for month 2 in year 1900
>>> dt.datetime.strptime(f"1904 {value}", "%Y %m/%d")
datetime.datetime(1904, 2, 29, 0, 0)

datetime.strptime(date_string, format) は次の式と等価です:

datetime(*(time.strptime(date_string, format)[0:6]))

ただし、書式 format に秒未満の成分やタイムゾーンオフセットの情報が含まれる場合は除きます。 これらの情報は datetime.strptime ではサポートされますが、time.strptime では破棄されます。

time オブジェクトでは、年、月、日の書式コードは使用すべきではありません。 time オブジェクトはこれらの値を持たないためです。 使用した場合、年には 1900、月と日には 1 が代入されます。

date オブジェクトに時、分、秒、マイクロ秒の書式コードを使うべきではありません。date オブジェクトはこれらの値を持たないためです。使用した場合は、これらの値に 0 が代入されます。

同じ理由で、現在のロケールの文字集合で表現できない Unicode コードポイントを含む書式文字列の対処もプラットフォーム依存です。 あるプラットフォームではそういったコードポイントはそのまま出力に出される一方、他のプラットフォームでは strftime が UnicodeError を送出したり、その代わりに空文字列を返したりするかもしれません。

注釈:

  1. この書式コードは、現在 strptime() ではサポートされていません。

  2. 書式は現在のロケールに依存するため、出力値について仮定する際は注意してください。 フィールドの順序は (例えば「月/日/年」と「日/月/年」のように) 異なり、出力に非 ASCII 文字が含まれる場合があります。

  3. strptime() メソッドは [1, 9999] の範囲の年数全てを構文解析できますが、 year < 1000 の範囲の年数は 0 埋めされた 4 桁の数字でなければなりません。

    バージョン 3.2 で変更: 以前のバージョンでは、 strftime() メソッドは years >= 1900 の範囲の年数しか扱えませんでした。

    バージョン 3.3 で変更: バージョン 3.2 では、 strftime() メソッドは years >= 1000 の範囲の年数しか扱えませんでした。

  4. strptime() メソッドで %p 指定子が出力の時フィールドに影響するのは、時の解析に %I 指定子を使う場合だけです。

  5. time モジュールと違い、 datetime モジュールはうるう秒をサポートしていません。

  6. strptime() メソッドと共に使われた場合、 %f 指定子は 1 桁から 6 桁の数字を受け付け、右側から0埋めされます。 %f は C 標準規格の書式文字セットの拡張です (とは言え、 datetime モジュールのオブジェクトそれぞれに実装されているので、どれででも使えます)。

  7. naive オブジェクトでは、書式コード %z、%:z および %Z は空文字列に置き換えられます。

    aware オブジェクトでは次のようになります:

    %z

    utcoffset() は ±HHMM[SS[.ffffff]] 形式の文字列に変換されます。ここで、 HH は UTC オフセットの時間を表す 2 桁の文字列、 MM は UTC オフセットの分数を表す 2 桁の文字列、 SS は UTC オフセットの秒数を表す 2 桁の文字列、 ffffff は UTC オフセットのマイクロ秒数を表す 6 桁の文字列です。 オフセットに秒未満の端数が無いときは ffffff 部分は省略され、オフセットに分未満の端数が無いときは ffffff 部分も SS 部分も省略されます。 例えば、 utcoffset() が timedelta(hours=-3, minutes=-30) を返す場合、 %z は文字列 '-0330' に置き換えられます。

    バージョン 3.7 で変更: UTC オフセットが分単位でなければならない制限が無くなりました。

    バージョン 3.7 で変更: strptime() メソッドに %z 指定子を指定した場合、UTC オフセットの時、分、秒の区切りにコロンを使えるようになりました。 例えば、'+010000' と '+01:00:00' はどちらも 1 時間のオフセットとして解析されます。 また、'Z' の指定は '+00:00' と等価です。

    %:z

    strftime() で使用すると、時、分、秒の間にコロン区切りが追加される点を除き、%z とまったく同じように動作します。

    strptime() で使用する場合、UTC オフセットの時、分、秒の区切りにはコロンが 必須 です。 例えば、'+01:00:00' は 1 時間のオフセットとして解析されますが、'+010000' は解析 されません。 また、'Z' の指定は '+00:00' と等価です。

    %Z

    In strftime(), %Z is replaced by an empty string if tzname() returns None; otherwise %Z is replaced by the returned value, which must be a string.

    strptime() は %Z に特定の値のみを受け入れます:

    1. 使用しているマシンのロケールによる time.tzname の任意の値

    2. ハードコードされた値 UTC または GMT

    つまり、日本に住んでいる場合は JST, UTC と GMT が有効な値であり、 EST はおそらく無効な値となります。無効な値の場合は ValueError を送出します。

    バージョン 3.2 で変更: %z 指定子が strptime() メソッドに与えられた場合、 aware な datetime オブジェクトが作成されます。返り値の tzinfo は timezone インスタンスになっています。

  8. strptime() メソッドと共に使われた場合、 %U と %W 指定子は、曜日と年(%Y)が指定された場合の計算でのみ使われます。

  9. %U および %W と同様に、 %V は曜日と ISO 年 (%G) が strptime() の書式文字列の中で指定された場合に計算でのみ使われます。 %G と %Y は互いに完全な互換性を持たないことにも注意してください。

  10. strptime() メソッドと共に使われるとき、書式 %d, %m, %H, %I, %M, %S, %j, %U, %W, %V では先行ゼロは任意です。 書式 %y では先行ゼロは必須です。

  11. strptime() で月と日を解析する場合は、常に書式に年を含めてください。 解析する値に年がない場合は、ダミーのうるう年を明示的に追加してください。 そうしないと、パーサが使用するデフォルトの年 (1900 年) はうるう年ではないため、コードがうるう日に対して例外を送出します。 ユーザーはうるう年ごとにこのバグに遭遇します。

    >>> month_day = "02/29"
    >>> dt.datetime.strptime(f"{month_day};1984", "%m/%d;%Y")  # うるう年のバグは起きない。
    datetime.datetime(1984, 2, 29, 0, 0)
    

    バージョン 3.15 で変更: 年なしで %d を使用すると、ValueError を送出するようになりました。

    バージョン 3.15 で非推奨、バージョン 3.17 で削除予定: 年なしで %e を含む書式文字列を使用して strptime() を呼び出すと、DeprecationWarning を出すようになりました。

脚注