8.1. datetime --- 基本的な日付型および時間型¶
バージョン 2.3 で追加.
datetime モジュールでは、日付や時間データを簡単な方法と複雑な方法の両方で操作するためのクラスを提供しています。日付や時刻を対象にした四則演算がサポートされている一方で、このモジュールの実装では出力の書式化や操作を目的とした属性の効率的な取り出しに焦点を絞っています。機能については、 time および calendar も参照下さい。
"naive" と "aware" の2種類の日付と時刻オブジェクトがあります。
aware オブジェクトは他の aware オブジェクトとの相対関係を把握出来るように、タイムゾーンや夏時間の情報のような、アルゴリズム的で政治的な適用可能な時間調節に関する知識を持っています。aware オブジェクトは解釈の余地のない特定の実時刻を表現するのに利用されます 1。
naive オブジェクトには他の日付時刻オブジェクトとの相対関係を把握するのに足る情報が含まれません。あるプログラム内の数字がメートルを表わしているのか、マイルなのか、それとも質量なのかがプログラムによって異なるように、naive オブジェクトが協定世界時 (UTC) なのか、現地時間なのか、それとも他のタイムゾーンなのかはそのプログラムに依存します。Naive オブジェクトはいくつかの現実的な側面を無視してしまうというコストを無視すれば、簡単に理解でき、うまく利用することができます。
aware オブジェクトを必要とするアプリケーションのために、 datetime と time オブジェクトは追加のタイムゾーン情報の属性 tzinfo を持ちます。 tzinfo には抽象クラス tzinfo のサブクラスのインスタンスを設定することができます。これらの tzinfo オブジェクトは UTC 時間からのオフセットやタイムゾーンの名前、夏時間が実施されるかの情報を保持しています。 datetime モジュールには tzinfo の具象クラスは提供されていないので注意してください。より深く詳細までタイムゾーンをサポートするかはアプリケーションに依存します。世界中の時刻の調整を決めるルールは合理的というよりかは政治的なもので、頻繁に変わり、都合のよい基準というものはありません。
datetime モジュールでは以下の定数を公開しています:
8.1.1. 利用可能なデータ型¶
-
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.tzinfo タイムゾーン情報オブジェクトの抽象基底クラスです。
datetimeおよびtimeクラスで用いられ、カスタマイズ可能な時刻修正の概念 (たとえばタイムゾーンや夏時間の計算)を提供します。
これらの型のオブジェクトは変更不可能 (immutable) です。
date 型のオブジェクトは常に naive です。
time や datetime 型のオブジェクトは naive かaware のどちらかになります。 datetime オブジェクト d は d.tzinfo が None でなく d.tzinfo.utcoffset(d) が None を返さなければ、aware になります。d.tzinfo が None であるか d.tzinfo が None でないが d.tzinfo.utcoffset(d) が None を返すと d は naive になります。 time のオブジェクト t は t.tzinfo が None でなく t.tzinfo.utcoffset(None) が None を返さないと aware になって、それ以外では t は naive になります。
naive なオブジェクトと aware なオブジェクトの区別は timedelta オブジェクトにはあてはまりません。
サブクラスの関係は以下のようになります:
object
timedelta
tzinfo
time
date
datetime
8.1.2. timedelta オブジェクト¶
timedelta オブジェクトは経過時間、すなわち二つの日付や時刻間の差を表します。
-
class
datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])¶ 全ての引数がオプションで、デフォルト値は
0です。引数は整数、長整数、浮動小数点数にすることができ、正でも負でもかまいません。days, seconds, microseconds だけが内部的に保持されます. 引数は以下のようにして変換されます:
1 ミリ秒は 1000 マイクロ秒に変換されます。
1 分は 60 秒に変換されます。
1 時間は 3600 秒に変換されます。
1 週間は 7 日に変換されます。
さらに、値が一意に表されるように days, seconds, microseconds が以下のように正規化されます
0 <= microseconds < 10000000 <= seconds < 3600*24(一日中の秒数)-999999999 <= days <= 999999999
引数のいずれかが浮動小数点であり、小数のマイクロ秒が存在する場合、小数のマイクロ秒は全ての引数から一度取り置かれ、それらの和は最も近いマイクロ秒に丸められます。浮動小数点の引数がない場合、値の変換と正規化の過程は厳密な (失われる情報がない) ものとなります。
日の値を正規化した結果、指定された範囲の外側になった場合には、
OverflowErrorが送出されます。負の値を正規化すると、一見混乱するような値になります。例えば、
>>> from datetime import timedelta >>> d = timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999)
クラス属性を以下に示します:
-
timedelta.max¶ 最大の値を表す
timedeltaオブジェクトで、timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)です。
正規化のために、 timedelta.max > -timedelta.min となるので注意してください。 -timedelta.max は timedelta オブジェクトとして表現することができません。
インスタンスの属性 (読み込みのみ):
属性 |
|
|---|---|
|
両端値を含む -999999999 から 999999999 の間 |
|
両端値を含む 0 から 86399 の間 |
|
両端値を含む 0 から 999999 の間 |
サポートされている操作を以下に示します:
演算 |
結果 |
|---|---|
|
t2 と t3 の和。演算後、t1-t2 == t3 および t1-t3 == t2 は真になります。(1) |
|
t2 と t3 の差。演算後、t1 == t2 - t3 および t2 == t1 + t3 は真になります。(1) |
|
時間差と(長)整数の積。演算後、t1 // i == t2 は |
一般的に、t1 * i == t1 * (i-1) + t1 は真となります。(1) |
|
|
floor が計算され、余りは (もしあれば) 捨てられます。(3) |
|
同じ値を持つ |
|
|
|
|
|
|
|
|
注釈:
この演算は正確ですが、オーバフローするかもしれません。
この演算は正確であり、オーバフローしないはずです。
0 による除算は
ZeroDivisionErrorを送出します。-timedelta.max は
timedeltaオブジェクトで表現することができません。timedeltaオブジェクトの文字列表現は内部表現に類似した形に正規化されます。そのため負の timedelta はいくぶん珍しい結果となります。例えば:>>> timedelta(hours=-5) datetime.timedelta(-1, 68400) >>> print(_) -1 day, 19:00:00
上に列挙した操作に加えて、 timedelta オブジェクトは date および datetime オブジェクトとの間で加減算をサポートしています (下を参照してください)。
timedelta オブジェクト間の比較はサポートされており、より小さい経過時間を表す timedelta オブジェクトがより小さい timedelta と見なされます。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、 timedelta オブジェクトと異なる型のオブジェクトが比較されると、比較演算子が == または != でないかぎり TypeError が送出されます。後者の場合、それぞれ False または True を返します。
timedelta オブジェクトはハッシュ可能(hashable) つまり、辞書のキーとして利用可能) であり、効率的な pickle 化をサポートします。また、ブール演算コンテキストでは、 timedelta オブジェクトは timedelta(0) に等しくない場合かつそのときに限り真となります。
インスタンスメソッド:
-
timedelta.total_seconds()¶ この期間に含まれるトータルの秒数を返します。 true division が有効な場合の、
(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6と同じです。非常に長い期間 (多くのプラットフォームでは270年以上) については、このメソッドはマイクロ秒の精度を失うことがあることに注意してください。
バージョン 2.7 で追加.
使用例:
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600) # adds up to 365 days
>>> year.total_seconds()
31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
>>> ten_years, ten_years.days // 365
(datetime.timedelta(3650), 10)
>>> nine_years = ten_years - year
>>> nine_years, nine_years.days // 365
(datetime.timedelta(3285), 9)
>>> three_years = nine_years // 3;
>>> three_years, three_years.days // 365
(datetime.timedelta(1095), 3)
>>> abs(three_years - ten_years) == 2 * three_years + year
True
8.1.3. date オブジェクト¶
date オブジェクトは日付 (年、月、および日) を表します。日付は理想的なカレンダー、すなわち現在のグレゴリオ暦を過去と未来の両方向に無限に延長したもので表されます。 1 年の 1 月 1 日は日番号 1, 1 年 1 月 2 日は日番号 2,となっていきます。この暦法は、全ての計算における基本カレンダーである、 Dershowitz と Reingold の書籍 Calendrical Calculations における先発グレゴリオ暦 (proleptic Gregorian) の定義に一致します。
-
class
datetime.date(year, month, day)¶ 全ての引数が必要です。引数は整数または長整数で、以下の範囲に入らなければなりません:
MINYEAR <= year <= MAXYEAR1 <= month <= 121 <= day <= 指定された月と年における日数
範囲を超えた引数を与えた場合、
ValueErrorが送出されます。
他のコンストラクタ、および全てのクラスメソッドを以下に示します:
-
classmethod
date.today()¶ 現在のローカルな日付を返します。
date.fromtimestamp(time.time())と等価です。
-
classmethod
date.fromtimestamp(timestamp)¶ time.time()で返されるような POSIX タイムスタンプに対応するローカルな日付を返します。 timestamp がプラットフォームの C 関数localtime()がサポートする値の範囲から外れていた場合、ValueErrorを送出するかもしれません。この範囲は通常は 1970 年から 2038 年までに制限されています。タイムスタンプの表記にうるう秒を含める非 POSIX なシステムでは、うるう秒はfromtimestamp()では無視されます。
-
classmethod
date.fromordinal(ordinal)¶ 先発グレゴリオ暦による序数に対応する日付を返します。 1 年 1 月 1 日が序数 1 となります。
1 <= ordinal <= date.max.toordinal()でない場合、ValueErrorが送出されます。任意の日付 d に対し、date.fromordinal(d.toordinal()) == dとなります。
以下にクラス属性を示します:
-
date.min¶ 表現できる最も古い日付で、
date(MINYEAR, 1, 1)です。
-
date.max¶ 表現できる最も新しい日付で、
date(MAXYEAR, 12, 31)です。
-
date.resolution¶ 等しくない日付オブジェクト間の最小の差で、
timedelta(days=1)です。
インスタンスの属性 (読み込みのみ):
-
date.month¶ 両端値を含む 1 から 12 までの値です。
-
date.day¶ 1 から与えられた月と年における日数までの値です。
サポートされている操作を以下に示します:
演算 |
結果 |
|---|---|
|
date2 はから date1 から |
|
|
|
(3) |
|
date1 が時刻として date2 よりも前を表す場合に、date1 は date2 よりも小さいと見なされます。(4) |
注釈:
date2 は
timedelta.days > 0の場合進む方向に、timedelta.days < 0の場合戻る方向に移動します。演算後は、date2 - date1 == timedelta.daysとなります。timedelta.secondsおよびtimedelta.microsecondsは無視されます。date2.yearがMINYEARになってしまったり、MAXYEARより大きくなってしまう場合にはOverflowErrorが送出されます。この操作は date1 + (-timedelta) と等価ではありません。なぜならば、date1 - timedelta がオーバフローしない場合でも、-timedelta 単体がオーバフローする可能性があるからです。
timedelta.secondsおよびtimedelta.microsecondsは無視されます。この演算は厳密で、オーバフローしません。timedelta.seconds および timedelta.microseconds は 0 で、演算後には date2 + timedelta == date1 となります。
別の言い方をすると、
date1.toordinal() < date2.toordinal()であり、かつそのときに限りdate1 < date2となります。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、dateオブジェクトと異なる型のオブジェクトが比較されるとTypeErrorが送出されます。しかしながら、被比較演算子のもう一方がtimetuple()属性を持つ場合にはNotImplementedが返されます。このフックにより、他種の日付オブジェクトに型混合比較を実装するチャンスを与えています。そうでない場合、dateオブジェクトと異なる型のオブジェクトが比較されると、比較演算子が==または!=でないかぎりTypeErrorが送出されます。後者の場合、それぞれFalseまたはTrueを返します。
date オブジェクトは辞書のキーとして用いることができます。ブール演算コンテキストでは、全ての date オブジェクトは真であるとみなされます。
インスタンスメソッド:
-
date.replace(year, month, day)¶ キーワード引数で指定されたパラメタが置き換えられることを除き、同じ値を持つ
dateオブジェクトを返します。例えば、d == date(2002, 12, 31)とすると、d.replace(day=26) == date(2002, 12, 26)となります。
-
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()¶ 3 要素のタプル (ISO 年、ISO 週番号、ISO 曜日) を返します。
ISO カレンダーはグレゴリオ暦の変種として広く用いられています。 細かい説明については https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm を参照してください。
ISO 年は完全な週が 52 または 53 週あり、週は月曜から始まって日曜に終わります。ISO 年でのある年における最初の週は、その年の木曜日を含む最初の (グレゴリオ暦での) 週となります。この週は週番号 1 と呼ばれ、この木曜日での ISO 年はグレゴリオ暦における年と等しくなります。
例えば、2004 年は木曜日から始まるため、ISO 年の最初の週は 2003 年 12 月 29 日、月曜日から始まり、2004 年 1 月 4 日、日曜日に終わります。従って、
date(2003, 12, 29).isocalendar() == (2004, 1, 1)であり、かつdate(2004, 1, 4).isocalendar() == (2004, 1, 7)となります。
-
date.isoformat()¶ ISO 8601 形式、'YYYY-MM-DD' の日付を表す文字列を返します。例えば、
date(2002, 12, 4).isoformat() == '2002-12-04'となります。
-
date.ctime()¶ 日付を表す文字列を、例えば
date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002'のようにして返します。ネイティブの C 関数ctime()(time.ctime()はこの関数を呼び出しますが、date.ctime()は呼び出しません) が C 標準に準拠しているプラットフォームでは、d.ctime()はtime.ctime(time.mktime(d.timetuple()))と等価です。
-
date.strftime(format)¶ 明示的な書式文字列で制御された、日付を表現する文字列を返します。 時間、分、秒を表す書式化コードは値 0 になります。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
-
date.__format__(format)¶ date.strftime()と同等です。これのおかげでstr.format()を使うときに、dateのための書式文字列を指定できます。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
イベントまでの日数を数える例を示します:
>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = 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 と併用する例を示します:
>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)
>>> t = d.timetuple()
>>> for i in t:
... print i
2002 # year
3 # month
11 # day
0
0
0
0 # weekday (0 = Monday)
70 # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:
... print i
2002 # ISO year
11 # ISO week number
1 # ISO day number ( 1 = Monday )
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'
8.1.4. datetime オブジェクト¶
datetime オブジェクトは date オブジェクトおよび time オブジェクトの全ての情報が入っている単一のオブジェクトです。 date オブジェクトと同様に、 datetime は現在のグレゴリオ暦が両方向に延長されているものと仮定します; また、 time オブジェクトと同様に, datetime は毎日が厳密に 3600*24 秒であると仮定します。
以下にコンストラクタを示します:
-
class
datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])¶ 年、月、および日の引数は必須です。 tzinfo は
Noneまたはtzinfoクラスのサブクラスのインスタンスにすることができます。残りの引数は整数または長整数で、以下のような範囲に入ります:MINYEAR <= year <= MAXYEAR1 <= month <= 121 <= day <= 指定された月と年における日数0 <= hour < 240 <= minute < 600 <= second < 600 <= microsecond < 1000000
範囲を超えた引数を与えた場合、
ValueErrorが送出されます。
他のコンストラクタ、および全てのクラスメソッドを以下に示します:
-
classmethod
datetime.today()¶ 現在のローカルな
datetimeを返します。tzinfoはNoneです。 この関数はdatetime.fromtimestamp(time.time())と等価です。now(),fromtimestamp()も参照してください。
-
classmethod
datetime.now([tz])¶ 現在のローカルな日付および時刻を返します。オプションの引数 tz が
Noneであるか指定されていない場合、このメソッドはtoday()と同様ですが、可能ならばtime.time()タイムスタンプを通じて得ることができる、より高い精度で時刻を提供します (例えば、プラットフォームが C 関数gettimeofday()をサポートする場合には可能なことがあります)。tz が
Noneでない場合、 tz はtzinfoのサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。 この場合、結果はtz.fromutc(datetime.utcnow().replace(tzinfo=tz))と等価になります。today(),utcnow()も参照してください。
-
classmethod
datetime.utcnow()¶ tzinfoがNoneである現在の UTC の日付および時刻を返します。これはnow()と似ていますが、 naive なdatetimeオブジェクトとして現在の UTC 日付および時刻を返します。now()も参照してください。
-
classmethod
datetime.fromtimestamp(timestamp[, tz])¶ time.time()が返すような、 POSIX タイムスタンプに対応するローカルな日付と時刻を返します。オプションの引数 tz がNoneであるか、指定されていない場合、タイムスタンプはプラットフォームのローカルな日付および時刻に変換され、返されるdatetimeオブジェクトは naive なものになります。tz が
Noneでない場合、 tz はtzinfoのサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。 この場合、結果はtz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))と等価になります。タイムスタンプがプラットフォームの C 関数
localtime()やgmtime()でサポートされている範囲を超えた場合、fromtimestamp()はValueErrorを送出することがあります。この範囲はよく 1970 年から 2038 年に制限されています。うるう秒がタイムスタンプの概念に含まれている非 POSIX システムでは、fromtimestamp()はうるう秒を無視します。このため、秒の異なる二つのタイムスタンプが同一のdatetimeオブジェクトとなることが起こり得ます。utcfromtimestamp()も参照してください。
-
classmethod
datetime.utcfromtimestamp(timestamp)¶ POSIX タイムスタンプに対応する、
tzinfoがNoneの UTC でのdatetimeを返します。タイムスタンプがプラットフォームにおける C 関数localtime()でサポートされている範囲を超えている場合にはValueErrorを送出します。これはたいてい 1970 年から 2038 年に制限されています。fromtimestamp()も参照してください。
-
classmethod
datetime.fromordinal(ordinal)¶ 1 年 1 月 1 日を序数 1 とする早期グレゴリオ暦序数に対応する
datetimeオブジェクトを返します。1 <= ordinal <= datetime.max.toordinal()でなければValueErrorが送出されます。 返されるオブジェクトの時間、分、秒、およびマイクロ秒はすべて 0 で、tzinfoはNoneとなっています。
-
classmethod
datetime.combine(date, time)¶ 日付部分が与えられた
dateオブジェクトと等しく、時刻部分とtzinfo属性が与えられたtimeオブジェクトと等しい、新しいdatetimeオブジェクトを返します。 任意のdatetimeオブジェクト d でd == datetime.combine(d.date(), d.timetz())が成立します。 date がdatetimeオブジェクトだった場合、その時刻部分とtzinfo属性は無視されます。
-
classmethod
datetime.strptime(date_string, format)¶ date_string に対応した
datetimeを返します。 format にしたがって構文解析されます。これは、datetime(*(time.strptime(date_string, format)[0:6]))と等価です。 date_stringとformatがtime.strptime()で構文解析できない場合や、この関数が時刻タプルを返してこない場合にはValueErrorを送出します。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。バージョン 2.5 で追加.
以下にクラス属性を示します:
インスタンスの属性 (読み込みのみ):
-
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)を満たします。
サポートされている操作を以下に示します:
演算 |
結果 |
|---|---|
|
(1) |
|
(2) |
|
(3) |
|
datetime2 は datetime1 から時間 timedelta 移動したもので、
timedelta.days> 0 の場合未来へ、timedelta.days< 0 の場合過去へ移動します。 結果は入力の datetime と同じtzinfo属性を持ち、演算後には datetime2 - datetime1 == timedelta となります。 datetime2.year がMINYEARよりも小さいか、MAXYEARより大きい場合にはOverflowErrorが送出されます。 入力が aware なオブジェクトの場合でもタイムゾーン修正は全く行われません。datetime2 + timedelta == datetime1 となるような datetime2 を計算します。 ちなみに、結果は入力の datetime と同じ
tzinfo属性を持ち、入力が aware でもタイムゾーン修正は全く行われません。 この操作は date1 + (-timedelta) と等価ではありません。 なぜならば、 date1 - timedelta がオーバフローしない場合でも、-timedelta 単体がオーバフローする可能性があるからです。datetimeからdatetimeの減算は両方の被演算子が naive であるか、両方とも aware である場合にのみ定義されています。片方が aware でもう一方が naive の場合、TypeErrorが送出されます。両方とも naive か、両方とも aware で同じ
tzinfo属性を持つ場合、tzinfo属性は無視され、結果はdatetime2 + t == datetime1であるようなtimedeltaオブジェクト t となります。 この場合タイムゾーン修正は全く行われません。両方が aware で異なる
tzinfo属性を持つ場合、a-bは a および b をまず naive な UTC datetime オブジェクトに変換したかのようにして行います。 演算結果は決してオーバフローを起こさないことを除き、(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())と同じになります。datetime1 が時刻として datetime2 よりも前を表す場合に、datetime1 は datetime2 よりも小さいと見なされます。
native と aware を比較しようとすると
TypeErrorが送出されます。比較対象が両方とも aware であり、同じtzinfo属性を持つ場合、tzinfoは無視され datetime だけで比較が行われます。比較対象が両方とも aware であり、異なるtzinfo属性を持つ場合、まず最初に (self.utcoffset()で取得できる) それぞれの UTC オフセットを引く調整が行われます。注釈
型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、被演算子のもう一方が
datetimeオブジェクトと異なる型のオブジェクトの場合にはTypeErrorが送出されます。しかしながら、被比較演算子のもう一方がtimetuple()属性を持つ場合にはNotImplementedが返されます。このフックにより、他種の日付オブジェクトに型混合比較を実装するチャンスを与えています。そうでない場合,datetimeオブジェクトと異なる型のオブジェクトが比較されると、比較演算子が==または!=でないかぎりTypeErrorが送出されます。後者の場合、それぞれFalseまたはTrueを返します。
datetime オブジェクトは辞書のキーとして用いることができます。ブール演算コンテキストでは、全ての datetime オブジェクトは真であるとみなされます。
インスタンスメソッド:
-
datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])¶ キーワード引数で指定した属性の値を除き、同じ属性をもつ datetime オブジェクトを返します。メンバに対する変換を行わずに aware な datetime オブジェクトから naive な datetime オブジェクトを生成するために、
tzinfo=Noneを指定することもできます。
-
datetime.astimezone(tz)¶ tz を新たに
tzinfo属性 として持つdatetimeオブジェクトを返します。 日付および時刻データを調整して、返り値が self と同じ UTC 時刻を持ち、 tz におけるローカルな時刻を表すようにします。tz は
tzinfoのサブクラスのインスタンスでなければならず、 インスタンスのutcoffset()およびdst()メソッドはNoneを返してはなりません。 self は aware でなくてはなりませ ん (self.tzinfoがNoneであってはならず、かつself.utcoffset()はNoneを返してはなりません)。self.tzinfoが tz の場合、self.astimezone(tz)は self に等しくなります: 日付および時刻データメンバに対する調整は行われません。そうでない場合、結果はタイムゾーン tz におけるローカル時刻で、 self と同じ UTC 時刻を表すようになります:astz = dt.astimezone(tz)とした後、astz - astz.utcoffset()は通常dt - dt.utcoffset()と同じ日付および時刻データメンバを持ちます。tzinfoクラスに関する議論では、夏時間 (Daylight Saving time) の遷移境界では上の等価性が成り立たないことを説明しています (tz が標準時と夏時間の両方をモデル化している場合のみの問題です)。単にタイムゾーンオブジェクト tz を
datetimeオブジェクト dt に追加したいだけで、日付や時刻データへの調整を行わないのなら、dt.replace(tzinfo=tz)を使ってください。単に aware なdatetimeオブジェクト dt からタイムゾーンオブジェクトを除去したいだけで、日付や時刻データの変換を行わないのなら、dt.replace(tzinfo=None)を使ってください。デフォルトの
tzinfo.fromutc()メソッドをtzinfoのサブクラスで上書きして,astimezone()が返す結果に影響を及ぼすことができます。エラーの場合を無視すると、astimezone()は以下のように動作します:def astimezone(self, tz): if self.tzinfo is tz: return self # Convert self to UTC, and attach the new time zone object. utc = (self - self.utcoffset()).replace(tzinfo=tz) # Convert from UTC to tz's local time. return tz.fromutc(utc)
-
datetime.utcoffset()¶ tzinfoがNoneの場合、Noneを返し、そうでない場合にはself.tzinfo.utcoffset(self)を返します。 後者の式がNoneか、1 日以下の大きさを持つ経過時間を表すtimedeltaオブジェクトのいずれかを返さない場合には例外を送出します。
-
datetime.dst()¶ tzinfoがNoneの場合Noneを返し、そうでない場合にはself.tzinfo.dst(self)を返します。 後者の式がNoneもしくは、1 日未満の経過時間を表すtimedeltaオブジェクトのいずれかを返さない場合には例外を送出します。
-
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.timetuple()と同じであり、d.dst()の返す内容にかかわらずtm_isdstが 0 に強制される点だけが異なります。 DST が UTC 時刻に影響を及ぼすことは決してありません。d が aware の場合、 d から
d.utcoffset()が差し引かれて UTC 時刻に正規化され、正規化された時刻のtime.struct_timeを返します。tm_isdstは 0 に強制されます。 d.year がMINYEARやMAXUEARで、UTC への修正の結果表現可能な年の境界を越えた場合には、戻り値のtm_yearメンバはMINYEAR-1 またはMAXYEAR+1 になることがあります。
-
datetime.toordinal()¶ 先発グレゴリオ暦における日付序数を返します。
self.date().toordinal()と同じです。
-
datetime.weekday()¶ 月曜日を 0、日曜日を 6 として、曜日を整数で返します。
self.date().weekday()と同じです。isoweekday()も参照してください。
-
datetime.isoweekday()¶ 月曜日を 1、日曜日を 7 として、曜日を整数で返します。
self.date().isoweekday()と等価です。weekday()、isocalendar()も参照してください。
-
datetime.isocalendar()¶ 3 要素のタプル (ISO 年、ISO 週番号、ISO 曜日) を返します。
self.date().isocalendar()と等価です。
-
datetime.isoformat([sep])¶ 日付と時刻を ISO 8601 形式、すなわち YYYY-MM-DDTHH:MM:SS.mmmmmm か、
microsecondが 0 の場合には YYYY-MM-DDTHH:MM:SS で表した文字列を返します。utcoffset()がNoneを返さない場合、 UTC からのオフセットを時間と分を表した (符号付きの) 6 文字からなる 文字列が追加されます: すなわち、 YYYY-MM- DDTHH:MM:SS.mmmmmm+HH:MM となるか、microsecondがゼロの場合には YYYY-MM- DDTHH:MM:SS+HH:MM となります。オプションの引数 sep (デフォルトでは
'T'です) は 1 文字のセパレータで、結果の文字列の日付と時刻の間に置かれます。例えば、>>> from datetime import tzinfo, timedelta, datetime >>> class TZ(tzinfo): ... def utcoffset(self, dt): return timedelta(minutes=-399) ... >>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') '2002-12-25 00:00:00-06:39'
-
datetime.ctime()¶ 日付を表す文字列を、例えば
datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec 4 20:30:40 2002'のようにして返します。ネイティブの C 関数ctime()(time.ctime()はこの関数を呼び出しますが、datetime.ctime()は呼び出しません) が C 標準に準拠しているプラットフォームでは、d.ctime()はtime.ctime(time.mktime(d.timetuple()))と等価です。
-
datetime.strftime(format)¶ 明示的な書式化文字列で制御された、日付および時刻を表現する文字列を返します。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
-
datetime.__format__(format)¶ datetime.strftime()と同等です。これのおかげでstr.format()を使うときに、datetimeのための書式文字列を指定できます。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
datetime オブジェクトを使う例:
>>> from datetime import datetime, date, time
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now() or datetime.utcnow()
>>> datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1
>>> datetime.utcnow()
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:
... print it
...
2006 # year
11 # month
21 # day
16 # hour
30 # minute
0 # second
1 # weekday (0 = Monday)
325 # number of days since 1st January
-1 # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:
... print it
...
2006 # ISO year
47 # ISO week
2 # ISO weekday
>>> # Formatting datetime
>>> dt.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(dt, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'
datetime を tzinfo と組み合わせて使う:
>>> from datetime import timedelta, datetime, tzinfo
>>> class GMT1(tzinfo):
... def utcoffset(self, dt):
... return timedelta(hours=1) + self.dst(dt)
... def dst(self, dt):
... # DST starts last Sunday in March
... d = datetime(dt.year, 4, 1) # ends last Sunday in October
... self.dston = d - timedelta(days=d.weekday() + 1)
... d = datetime(dt.year, 11, 1)
... self.dstoff = d - timedelta(days=d.weekday() + 1)
... if self.dston <= dt.replace(tzinfo=None) < self.dstoff:
... return timedelta(hours=1)
... else:
... return timedelta(0)
... def tzname(self,dt):
... return "GMT +1"
...
>>> class GMT2(tzinfo):
... def utcoffset(self, dt):
... return timedelta(hours=2) + self.dst(dt)
... def dst(self, dt):
... d = datetime(dt.year, 4, 1)
... self.dston = d - timedelta(days=d.weekday() + 1)
... d = datetime(dt.year, 11, 1)
... self.dstoff = d - timedelta(days=d.weekday() + 1)
... if self.dston <= dt.replace(tzinfo=None) < self.dstoff:
... return timedelta(hours=1)
... else:
... return timedelta(0)
... def tzname(self,dt):
... return "GMT +2"
...
>>> gmt1 = GMT1()
>>> # Daylight Saving Time
>>> dt1 = datetime(2006, 11, 21, 16, 30, tzinfo=gmt1)
>>> dt1.dst()
datetime.timedelta(0)
>>> dt1.utcoffset()
datetime.timedelta(0, 3600)
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=gmt1)
>>> dt2.dst()
datetime.timedelta(0, 3600)
>>> dt2.utcoffset()
datetime.timedelta(0, 7200)
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(GMT2())
>>> dt3
datetime.datetime(2006, 6, 14, 14, 0, tzinfo=<GMT2 object at 0x...>)
>>> dt2
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...>)
>>> dt2.utctimetuple() == dt3.utctimetuple()
True
8.1.5. time オブジェクト¶
time オブジェクトは (ローカルの) 日中時刻を表現します。この時刻表現は特定の日の影響を受けず、 tzinfo オブジェクトを介した修正の対象となります。
-
class
datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]])¶ 全ての引数はオプションです。 tzinfo は
Noneまたはtzinfoクラスのサブクラスのインスタンスにすることができます。残りの引数は整数または長整数で、以下のような範囲に入ります:0 <= hour < 240 <= minute < 600 <= second < 600 <= microsecond < 1000000.
引数がこれらの範囲外にある場合、
ValueErrorが送出されます。 tzinfo のデフォルト値がNoneである以外のデフォルト値は0です。
以下にクラス属性を示します:
-
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)を満たします。
サポートされている操作を以下に示します:
a が時間的に b に先行している場合に a は b より小さいとみなす、
timeとtimeの比較。 native と aware を比較しようとするとTypeErrorが送出されます。比較対象が両方とも aware であり、同じtzinfo属性を持つ場合、tzinfoは無視され datetime だけで比較が行われます。比較対象が両方とも aware であり、異なるtzinfo属性を持つ場合、まず最初に (self.utcoffset()で取得できる) それぞれの UTC オフセットを引く調整が行われます。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、timeオブジェクトと異なる型のオブジェクトが比較されると、比較演算子が==または!=でないかぎりTypeErrorが送出されます。後者の場合、それぞれFalseまたはTrueを返します。ハッシュ化、辞書のキーとしての利用
効率的な pickle 化
ブール演算コンテキストでは,
timeオブジェクトは、分に変換し,utcoffset()(Noneを返した場合には0) を差し引いて変換した後の結果がゼロでない場合、かつそのときに限って真とみなされます。
インスタンスメソッド:
-
time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])¶ キーワード引数で指定したメンバの値を除き、同じ値をもつ
timeオブジェクトを返します。データに対する変換を行わずに aware なtimeオブジェクトから naive なtimeオブジェクトを生成するために、tzinfo=Noneを指定することもできます。
-
time.isoformat()¶ 日付と時刻を ISO 8601 形式、すなわち HH:MM:SS.mmmmmm か、
microsecondが 0 の場合には HH:MM:SS で表した文字列を返します。utcoffset()がNoneを返さない場合、 UTC からのオフセットを時間と分を表した (符号付きの) 6 文字からなる 文字列が追加されます: すなわち、 HH:MM:SS.mmmmmm+HH:MM となるか、microsecondが 0 の場合には HH:MM:SS+HH:MM となります
-
time.strftime(format)¶ 明示的な書式文字列で制御された、時刻を表現する文字列を返します。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
-
time.__format__(format)¶ time.strftime()と同等です。これのおかげでstr.format()を使うときに、timeのための書式文字列を指定できます。完全な書式化ディレクティブのリストについては strftime() と strptime() の振る舞い を参照してください。
-
time.utcoffset()¶ tzinfoがNoneの場合Noneを返し、そうでない場合にはself.tzinfo.utcoffset(None)を返します。 後者の式がNoneもしくは、1 日未満の経過時間を表すtimedeltaオブジェクトのいずれかを返さない場合には例外を送出します。
-
time.dst()¶ tzinfoがNoneの場合Noneを返し、そうでない場合にはself.tzinfo.dst(None)を返します。 後者の式がNoneもしくは、 1日未満の経過時間を表すtimedeltaオブジェクトのいずれかを返さない場合には例外を送出します。
-
time.tzname()¶ tzinfoがNoneの場合Noneを返し、そうでない場合にはself.tzinfo.tzname(None)を返します。 後者の式がNoneか文字列オブジェクトのいずれかを返さない場合には例外を送出します。
例:
>>> from datetime import time, tzinfo, timedelta
>>> class GMT1(tzinfo):
... def utcoffset(self, dt):
... return timedelta(hours=1)
... def dst(self, dt):
... return timedelta(0)
... def tzname(self,dt):
... return "Europe/Prague"
...
>>> t = time(12, 10, 30, tzinfo=GMT1())
>>> t
datetime.time(12, 10, 30, tzinfo=<GMT1 object at 0x...>)
>>> gmt = GMT1()
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'Europe/Prague'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 Europe/Prague'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'
8.1.6. tzinfo オブジェクト¶
-
class
datetime.tzinfo¶ これは抽象基底クラスです。つまり、このクラスは直接インスタンス化して利用しません。具体的なサブクラスを派生し、 (少なくとも) 利用したい
datetimeのメソッドが必要とするtzinfoの標準メソッドを実装してやる必要があります。datetimeモジュールでは、tzinfoの具体的なサブクラスは何ら提供していません。tzinfo(の具体的なサブクラス) のインスタンスはdatetimeおよびtimeオブジェクトのコンストラクタに渡すことができます。後者のオブジェクトでは、データ属性をローカル時刻におけるものとして見ており、tzinfoオブジェクトはローカル時刻の UTC からのオフセット、タイムゾーンの名前、 DST オフセットを、渡された日付および時刻オブジェクトからの相対で示すためのメソッドを提供します。pickle 化についての特殊な要求事項:
tzinfoのサブクラスは引数なしで呼び出すことのできる__init__()メソッドを持たなければなりません。そうでなければ、 pickle 化することはできますがおそらく unpickle 化することはできないでしょう。これは技術的な側面からの要求であり、将来緩和されるかもしれません。tzinfoの具体的なサブクラスでは、以下のメソッドを実装する必要があります。厳密にどのメソッドが必要なのかは、 aware なdatetimeオブジェクトがこのサブクラスのインスタンスをどのように使うかに依存します。不確かならば、単に全てを実装してください。
-
tzinfo.utcoffset(self, dt)¶ ローカル時間の UTC からのオフセットを、 UTC から東向きを正とした分で返します。ローカル時間が UTC の西側にある場合、この値は負になります。このメソッドは UTC からのオフセットの総計を返すように意図されているので注意してください; 例えば、
tzinfoオブジェクトがタイムゾーンと DST 修正の両方を表現する場合、utcoffset()はそれらの合計を返さなければなりません。 UTC オフセットが未知である場合、Noneを返してください。そうでない場合には、返される値は -1439 から 1439 の両端を含む値 (1440 = 24*60 ; つまり、オフセットの大きさは 1 日より短くなくてはなりません) が分で指定されたtimedeltaオブジェクトでなければなりません。ほとんどのutcoffset()実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class
utcoffset()がNoneを返さない場合、dst()もNoneを返してはなりません。utcoffset()のデフォルトの実装はNotImplementedErrorを送出します。
-
tzinfo.dst(self, dt)¶ 夏時間 (DST) 修正を、 UTC から東向きを正とした分で返します。 DST 情報が未知の場合、
Noneが返されます。 DST が有効でない場合にはtimedelta(0)を返します。 DST が有効の場合、オフセットは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のサブクラスでは、この式はタイムゾーンにおける "標準オフセット (standard offset)" を表し、特定の日や時刻の事情ではなく地理的な位置にのみ依存していなくてはなりません。datetime.astimezone()の実装はこの事実に依存していますが、違反を検出することができません; 正しく実装するのはプログラマの責任です。tzinfoのサブクラスでこれを保証することができない場合、tzinfo.fromutc()の実装をオーバライドして、astimezone()に関わらず正しく動作するようにしてもかまいません。ほとんどの
dst()実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:def dst(self, dt): # a fixed-offset class: doesn't account for DST return timedelta(0)
もしくは
def dst(self, dt): # Code to set dston and dstoff to the time zone's DST # transition times based on the input dt.year, and expressed # in standard local time. Then if dston <= dt.replace(tzinfo=None) < dstoff: return timedelta(hours=1) else: return timedelta(0)
デフォルトの
dst()実装はNotImplementedErrorを送出します。
-
tzinfo.tzname(self, dt)¶ datetimeオブジェクト dt に対応するタイムゾーン名を文字列で返します。datetimeモジュールでは文字列名について何も定義しておらず、特に何かを意味するといった要求仕様もまったくありません。例えば、 "GMT","UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" は全て有効な応答となります。文字列名が未知の場合にはNoneを返してください。tzinfoのサブクラスでは、特に,tzinfoクラスが夏時間について記述している場合のように、渡された dt の特定の値によって異なった名前を返したい場合があるため、文字列値ではなくメソッドとなっていることに注意してください。デフォルトの
tzname()実装はNotImplementedErrorを送出します。
以下のメソッドは datetime や time オブジェクトにおいて、同名のメソッドが呼び出された際に応じて呼び出されます。 datetime オブジェクトは自身を引数としてメソッドに渡し、 time オブジェクトは引数として None をメソッドに渡します。従って、 tzinfo のサブクラスにおけるメソッドは引数 dt が None の場合と、 datetime の場合を受理するように用意しなければなりません。
None が渡された場合、最良の応答方法を決めるのはクラス設計者次第です。例えば、このクラスが tzinfo プロトコルと関係をもたないということを表明させたければ、 None が適切です。標準時のオフセットを見つける他の手段がない場合には、標準 UTC オフセットを返すために utcoffset(None) を使うともっと便利かもしれません。
datetime オブジェクトが datetime() メソッドの応答として返された場合、 dt.tzinfo は self と同じオブジェクトになります。ユーザが直接 tzinfo メソッドを呼び出さないかぎり、 tzinfo メソッドは dt.tzinfo と self が同じであることに依存します。その結果 tzinfo メソッドは dt がローカル時間であると解釈するので、他のタイムゾーンでのオブジェクトの振る舞いについて心配する必要がありません。
サブクラスでオーバーライドすると良い、もう 1 つの tzinfo のメソッドがあります:
-
tzinfo.fromutc(self, dt)¶ デフォルトの
datetime.astimezone()実装で呼び出されます。datetime.astimezone()から呼ばれた場合、dt.tzinfoは self であり、 dt の日付および時刻データは UTC 時刻を表しているものとして見えます。fromutc()の目的は、 self のローカル時刻に等しいdatetimeオブジェクトを返すことにより日付と時刻データメンバを修正することにあります。ほとんどの
tzinfoサブクラスではデフォルトのfromutc()実装を問題なく継承できます。デフォルトの実装は、固定オフセットのタイムゾーンや、標準時と夏時間の両方について記述しているタイムゾーン、そして DST 移行時刻が年によって異なる場合でさえ、扱えるくらい強力なものです。デフォルトのfromutc()実装が全ての場合に対して正しく扱うことができないような例は、標準時の (UTCからの) オフセットが引数として渡された特定の日や時刻に依存するもので、これは政治的な理由によって起きることがあります。デフォルトのastimezone()やfromutc()の実装は、結果が標準時オフセットの変化にまたがる何時間かの中にある場合、期待通りの結果を生成しないかもしれません。エラーの場合のためのコードを除き、デフォルトの
fromutc()の実装は以下のように動作します:def fromutc(self, dt): # raise ValueError error if dt.tzinfo is not self dtoff = dt.utcoffset() dtdst = dt.dst() # raise ValueError if dtoff is None or dtdst is None delta = dtoff - dtdst # this is self's standard offset if delta: dt += delta # convert to standard local time dtdst = dt.dst() # raise ValueError if dtdst is None if dtdst: return dt + dtdst else: return dt
以下に tzinfo クラスの使用例を示します:
from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
# A class building tzinfo objects for fixed-offset time zones.
# Note that FixedOffset(0, "UTC") is a different way to build a
# UTC tzinfo object.
class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC."""
def __init__(self, offset, name):
self.__offset = timedelta(minutes = offset)
self.__name = name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return ZERO
# A class capturing the platform's idea of local time.
import time as _time
STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
class LocalTimezone(tzinfo):
def utcoffset(self, dt):
if self._isdst(dt):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
# A complete implementation of current DST rules for major US time zones.
def first_sunday_on_or_after(dt):
days_to_go = 6 - dt.weekday()
if days_to_go:
dt += timedelta(days_to_go)
return dt
# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# http://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 1)
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
# Sunday in April and to end at 2am (DST time; 1am standard time) on the last
# Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 1)
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
# Sunday in April (the one on or after April 24) and to end at 2am (DST time;
# 1am standard time) on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006
class USTimeZone(tzinfo):
def __init__(self, hours, reprname, stdname, dstname):
self.stdoffset = timedelta(hours=hours)
self.reprname = reprname
self.stdname = stdname
self.dstname = dstname
def __repr__(self):
return self.reprname
def tzname(self, dt):
if self.dst(dt):
return self.dstname
else:
return self.stdname
def utcoffset(self, dt):
return self.stdoffset + self.dst(dt)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
return ZERO
assert dt.tzinfo is self
# Find start and end times for US DST. For years before 1967, return
# ZERO for no DST.
if 2006 < dt.year:
dststart, dstend = DSTSTART_2007, DSTEND_2007
elif 1986 < dt.year < 2007:
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
elif 1966 < dt.year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return ZERO
start = first_sunday_on_or_after(dststart.replace(year=dt.year))
end = first_sunday_on_or_after(dstend.replace(year=dt.year))
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
if start <= dt.replace(tzinfo=None) < end:
return HOUR
else:
return ZERO
Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
Central = USTimeZone(-6, "Central", "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")
標準時間 (standard time) および夏時間 (daylight time) の両方を記述している tzinfo のサブクラスでは、回避不能の難解な問題が年に 2 度あるので注意してください。具体的な例として、東部アメリカ時刻 (US Eastern, UTC -5000) を考えます。 EDT は 3 月の第二日曜日の 1:59 (EST) 以後に開始し、11 月の最初の日曜日の 1:59 (EDT) に終了します:
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 の形式をとる時刻は実際には無意味となります。従っ て、 astimezone(Eastern) は DST が開始する日には hour == 2 と なる結果を返すことはありません。 astimezone() がこのことを保証するようにするには、 tzinfo.dst() メソッドは "失われた時間" (東部時刻における 2:MM) が夏時間に存在することを考えなければなりません。
DST が終了する際 ("end" の並び) では、問題はさらに悪化します: 1 時間の間、ローカルの壁時計ではっきりと時刻をいえなくなります: それは夏時間の最後の 1 時間です。東部時刻では、その日の UTC での 5:MM に夏時間は終了します。ローカルの壁時計は 1:59 (夏時間) から 1:00 (標準時) に再び巻き戻されます。ローカルの時刻における 1:MM はあいまいになります。 astimezone() は二つの UTC 時刻を同じローカルの時刻に対応付けることでローカルの時計の振る舞いをまねます。東部時刻の例では、 5:MM および 6:MM の形式をとる UTC 時刻は両方とも、東部時刻に変換された際に 1:MM に対応づけられます。 astimezone() がこのことを保証するようにするには、 tzinfo.dst() は "繰り返された時間" が標準時に存在することを考慮しなければなりません。このことは、例えばタイムゾーンの標準のローカルな時刻に DST への切り替え時刻を表現することで簡単に設定することができます。
このようなあいまいさを許容できないアプリケーションは、ハイブリッドな tzinfo サブクラスを使って問題を回避しなければなりません; UTC や、他のオフセットが固定された tzinfo のサブクラス (EST (-5 時間の固定オフセット) のみを表すクラスや、 EDT (-4 時間の固定オフセット) のみを表すクラス) を使う限り、あいまいさは発生しません。
参考
- pytz
標準ライブラリには
tzinfoインスタンスはありませんが、サードパーティーのライブラリで (Olson データベースとしても知られる) IANA タイムゾーンデータベース を Python に提供するものが存在します: それが pytz です。pytz は最新の情報を含み、使用を推奨されています。
- IANA タイムゾーンデータベース
(しばしば tz や zoneinfo と呼ばれる) タイムゾーンデータベースはコードとデータを保持しており、それらは地球全体にわたる多くの代表的な場所のローカル時刻の履歴を表しています。政治団体によるタイムゾーンの境界、UTC オフセット、夏時間のルールの変更を反映するため、定期的にデータベースが更新されます。
8.1.7. strftime() と strptime() の振る舞い¶
date, datetime,および time オブジェクトは全て、明示的な書式文字列でコントロールして時刻表現文字列を生成するための strftime(format) メソッドをサポートしています。大雑把にいうと、 d.strftime(fmt) は time モジュールの time.strftime(fmt, d.timetuple()) のように動作します。ただし全てのオブジェクトが timetuple() メソッドをサポートしているわけではありません。
逆に datetime.strptime() クラスメソッドは日付や時刻に対応する書式文字列から datetime オブジェクトを生成します。 datetime.strptime(date_string, format) は datetime(*(time.strptime(date_string, format)[0:6])) と等価です。ただし、その書式に小数秒以下の要素またはタイムゾーン情報が含まれる、``datetime.strptime``ではサポートされるが``time.strptime``ではサポートされないような場合はその限りではありません。
time オブジェクトでは、年、月、日の値がないため、それらの書式化コードを使うことができません。無理矢理使った場合、年は 1900 に置き換えられ、月と日は 1 に置き換えられます。
date オブジェクトでは、時、分、秒、マイクロ秒の値がないため、それらの書式化コードを使うことができません。無理矢理使った場合、これらの値は 0 に置き換えられます。
Python はプラットフォームの C ライブラリの strftime() 関数を呼び出していて、プラットフォームごとにその実装が異なるのはよくあることなので、サポートされるフォーマット記号全体はプラットフォームごとに様々です。プラットフォームでサポートされているフォーマット記号全体を見るには、 strftime(3) のドキュメントを参照してください。
同じ理由で、現在のロケールの文字集合で表現できない Unicode コードポイントを含む書式文字列の対処もプラットフォーム依存です。
あるプラットフォームではそういったコードポイントはそのまま出力に出される一方、他のプラットフォームでは strftime が UnicodeError を送出したり、その代わりに空文字列を返したりするかもしれません。
以下のリストはC標準(1989年版)が要求する全ての書式化コードで、標準C実装があれば全ての環境で動作します。1999 年版の C 標準では書式化コードが追加されているので注意してください。
strftime() が正しく動作する年の厳密な範囲はプラットフォーム間で異なります。プラットフォームに関わらず、1900 年以前の年は使うことができません。
ディレクティブ |
意味 |
例 |
注釈 |
|---|---|---|---|
|
ロケールの曜日名を短縮形で表示します。 |
Sun, Mon, ..., Sat
(en_US);
So, Mo, ..., Sa
(de_DE)
|
(1) |
|
ロケールの曜日名を表示します。 |
Sunday, Monday, ...,
Saturday (en_US);
Sonntag, Montag, ...,
Samstag (de_DE)
|
(1) |
|
曜日を10進表記した文字列を表示します。0 が日曜日で、6 が土曜日を表します。 |
0, 1, ..., 6 |
|
|
0埋めした10進数で表記した月中の日にち。 |
01, 02, ..., 31 |
|
|
ロケールの月名を短縮形で表示します。 |
Jan, Feb, ..., Dec
(en_US);
Jan, Feb, ..., Dez
(de_DE)
|
(1) |
|
ロケールの月名を表示します。 |
January, February,
..., December (en_US);
Januar, Februar, ...,
Dezember (de_DE)
|
(1) |
|
0埋めした10進数で表記した月。 |
01, 02, ..., 12 |
|
|
0埋めした10進数で表記した世紀無しの年。 |
00, 01, ..., 99 |
|
|
西暦 (4桁) の 10 進表記を表します。 |
1970, 1988, 2001, 2013 |
|
|
0埋めした10進数で表記した時 (24時間表記)。 |
00, 01, ..., 23 |
|
|
0埋めした10進数で表記した時 (12時間表記)。 |
01, 02, ..., 12 |
|
|
ロケールの AM もしくは PM と等価な文字列になります。 |
AM, PM (en_US);
am, pm (de_DE)
|
(1), (2) |
|
0埋めした10進数で表記した分。 |
00, 01, ..., 59 |
|
|
0埋めした10進数で表記した秒。 |
00, 01, ..., 59 |
(3) |
|
10進数で表記したマイクロ秒 (左側から0埋めされます)。 |
000000, 000001, ..., 999999 |
(4) |
|
UTCオフセットを +HHMM もしくは -HHMM の形式で表示します (オブジェクトがnaiveであれば空文字列)。 |
(空文字列), +0000, -0400, +1030 |
(5) |
|
タイムゾーンの名前を表示します (オブジェクトがnaiveであれば空文字列)。 |
(空文字列), UTC, EST, CST |
|
|
0埋めした10進数で表記した年中の日にち。 |
001, 002, ..., 366 |
|
|
0埋めした10進数で表記した年中の週番号 (週の始まりは日曜日とする)。新年の最初の日曜日に先立つ日は 0週に属するとします。 |
00, 01, ..., 53 |
(6) |
|
0埋めした10進数で表記した年中の週番号 (週の始まりは月曜日とする)。新年の最初の月曜日に先立つ日は 0週に属するとします。 |
00, 01, ..., 53 |
(6) |
|
ロケールの日時を適切な形式で表します。 |
Tue Aug 16 21:30:00
1988 (en_US);
Di 16 Aug 21:30:00
1988 (de_DE)
|
(1) |
|
ロケールの日付を適切な形式で表します。 |
08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)
|
(1) |
|
ロケールの時間を適切な形式で表します。 |
21:30:00 (en_US);
21:30:00 (de_DE)
|
(1) |
|
文字 |
% |
注釈:
フォーマットは現在のロケールに依存するので、出力値に何か仮定を置くときは注意すべきです。フィールドの順序は様々で (例えば、"月/日/年" と "日/月/年") 、出力はロケールのデフォルトエンコーディングでエンコードされた Unicode 文字列を含むかもしれません (例えば、現在のロケールが
ja_JPだった場合、デフォルトエンコーディングはeucJP、SJIS、utf-8のいづれかです;locale.getlocale()を使って現在のロケールのエンコーディングを確認します) 。strptime()メソッドと共に使われた場合、%p指定子は出力の時間フィールドのみに影響し、%I指定子が使われたかのように振る舞います。%fは C 標準規格の書式化コードセットへの拡張です (ただし datetime オブジェクトとは分けて実装してあるので、常に使えます)。strptime()メソッドと共に使われた場合、%f指定子は 1 桁から 6 桁の数字を受け付け、右側から 0 埋めされます。バージョン 2.6 で追加.
naive オブジェクトでは、書式化コード
%zおよび%Zは空文字列に置き換えられます。aware オブジェクトでは以下のようになります:
%zutcoffset()は +HHMM あるいは -HHMM の形式をもった 5 文字の文字列に変換されます。HH は UTC オフセット時間を与える 2 桁の文字列で、 MM は UTC オフセット分を与える 2 桁の文字列です。例えば、utcoffset()がtimedelta(hours=-3, minutes=-30)を返した場合、%zは文字列'-0330'に置き換わります。%Ztzname()がNoneを返した場合、%Zは空文字列に置き換 わります。そうでない場合、%Zは返された値に置き換わりますが、 これは文字列でなければなりません。
strptime()メソッドと共に使われた場合、%Uと%W指定子は、年と曜日が指定された場合の計算でのみ使われます。
注記
- 1
もし相対性理論の効果を無視するならば、ですが
