datetime – 日付/時間の操作

目的:datetime モジュールは、日付や時間を解析、書式設定、計算するための関数やクラスを提供する
利用できるバージョン:2.3 以上

datetime モジュールの関数やクラスは、単独で同時に日付や時間を扱います。

時間

時間は time クラスで表されます。 time は、時・分・秒・マイクロ秒の属性をもちます。また、タイムゾーンの情報も含みます。 time インスタンスを初期化する引数はオプションで選択できますが、デフォルトは望むものとは言い難い 0 になります。

import datetime

t = datetime.time(1, 2, 3)
print t
print 'hour  :', t.hour
print 'minute:', t.minute
print 'second:', t.second
print 'microsecond:', t.microsecond
print 'tzinfo:', t.tzinfo
$ python datetime_time.py
01:02:03
hour  : 1
minute: 2
second: 3
microsecond: 0
tzinfo: None

time インスタンスは、日付に関連付けられていない時間のみを保持します。

import datetime

print 'Earliest  :', datetime.time.min
print 'Latest    :', datetime.time.max
print 'Resolution:', datetime.time.resolution

minmax のクラス属性は、1日の時間の有効範囲を表します。

$ python datetime_time_minmax.py
Earliest  : 00:00:00
Latest    : 23:59:59.999999
Resolution: 0:00:00.000001

timeresolution で取得できるのはマイクロ秒までに制限されます。

import datetime

for m in [ 1, 0, 0.1, 0.6 ]:
    try:
        print '%02.1f :' % m, datetime.time(0, 0, 0, microsecond=m)
    except TypeError, err:
        print 'ERROR:', err

実際、マイクロ秒に小数を使用すると TypeError が発生します。

$ python datetime_time_resolution.py
1.0 : 00:00:00.000001
0.0 : 00:00:00
0.1 : ERROR: integer argument expected, got float
0.6 : ERROR: integer argument expected, got float

日付

カレンダーの日付は date クラスで表されます。このインスタンスは、年・月・日の属性をもちます。 today() クラスメソッドで簡単に今日の日付を表せます。

import datetime

today = datetime.date.today()
print today
print 'ctime:', today.ctime()
print 'tuple:', today.timetuple()
print 'ordinal:', today.toordinal()
print 'Year:', today.year
print 'Mon :', today.month
print 'Day :', today.day

このサンプルは複数のフォーマットで今日の日付を表示します。

$ python datetime_date.py
2013-02-17
ctime: Sun Feb 17 00:00:00 2013
tuple: time.struct_time(tm_year=2013, tm_mon=2, tm_mday=17, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=48, tm_isdst=-1)
ordinal: 734916
Year: 2013
Mon : 2
Day : 17

(1年の1月1日から数え始める初期のグレゴリオ序数を使用して)整数からインスタンスを作成するクラスメソッドや POSIX タイムスタンプもあります。

import datetime
import time

o = 733114
print 'o:', o
print 'fromordinal(o):', datetime.date.fromordinal(o)
t = time.time()
print 't:', t
print 'fromtimestamp(t):', datetime.date.fromtimestamp(t)

このサンプルは fromordinal()fromtimestamp() が使用する値が違うことを説明します。

$ python datetime_date_fromordinal.py
o: 733114
fromordinal(o): 2008-03-13
t: 1361118741.83
fromtimestamp(t): 2013-02-17

time クラスと同様に、日付の有効範囲は minmax 属性で決められます。

import datetime

print 'Earliest  :', datetime.date.min
print 'Latest    :', datetime.date.max
print 'Resolution:', datetime.date.resolution

dateresolution で取得できるのは丸一日です。

$ python datetime_date_minmax.py
Earliest  : 0001-01-01
Latest    : 9999-12-31
Resolution: 1 day, 0:00:00

新たな date インスタンスを作成する別の方法は、既存の datereplace() メソッドを使用します。例えば、日と月はそのままで年を変更できます。

import datetime

d1 = datetime.date(2008, 3, 12)
print 'd1:', d1

d2 = d1.replace(year=2009)
print 'd2:', d2
$ python datetime_date_replace.py
d1: 2008-03-12
d2: 2009-03-12

タイムデルタ

replace() を使用することだけが未来/過去の日付を計算する方法ではありません。 datetimetimedelta を使用して基本的な日付計算ができます。日付の引き算をすると timedelta を生成します。 timedelta は足し算や引き算により別の日付を生成します。 timedelta の内部的な値は、日・秒・マイクロ秒で格納されます。

import datetime

print "microseconds:", datetime.timedelta(microseconds=1)
print "milliseconds:", datetime.timedelta(milliseconds=1)
print "seconds     :", datetime.timedelta(seconds=1)
print "minutes     :", datetime.timedelta(minutes=1)
print "hours       :", datetime.timedelta(hours=1)
print "days        :", datetime.timedelta(days=1)
print "weeks       :", datetime.timedelta(weeks=1)

コンストラクタへ渡される中間の値は、日、秒、マイクロ秒に変換されます。

$ python datetime_timedelta.py
microseconds: 0:00:00.000001
milliseconds: 0:00:00.001000
seconds     : 0:00:01
minutes     : 0:01:00
hours       : 1:00:00
days        : 1 day, 0:00:00
weeks       : 7 days, 0:00:00

日付計算

日付の計算は標準の算術演算子を使用します。 date オブジェクトを扱うこのサンプルは、新しい日付を計算する timedelta オブジェクトの使い方と、(マイナスのデルタ値を含む) timedelta を生成する date インスタンスの引き算を説明します。

import datetime

today = datetime.date.today()
print 'Today    :', today

one_day = datetime.timedelta(days=1)
print 'One day  :', one_day

yesterday = today - one_day
print 'Yesterday:', yesterday

tomorrow = today + one_day
print 'Tomorrow :', tomorrow

print 'tomorrow - yesterday:', tomorrow - yesterday
print 'yesterday - tomorrow:', yesterday - tomorrow
$ python datetime_date_math.py
Today    : 2013-02-17
One day  : 1 day, 0:00:00
Yesterday: 2013-02-16
Tomorrow : 2013-02-18
tomorrow - yesterday: 2 days, 0:00:00
yesterday - tomorrow: -2 days, 0:00:00

値の比較

datetime の両方とも、どちらの日時が早いか、遅いかを標準の演算子で比較できます。

import datetime
import time

print 'Times:'
t1 = datetime.time(12, 55, 0)
print '\tt1:', t1
t2 = datetime.time(13, 5, 0)
print '\tt2:', t2
print '\tt1 < t2:', t1 < t2

print 'Dates:'
d1 = datetime.date.today()
print '\td1:', d1
d2 = datetime.date.today() + datetime.timedelta(days=1)
print '\td2:', d2
print '\td1 > d2:', d1 > d2
$ python datetime_comparing.py
Times:
        t1: 12:55:00
        t2: 13:05:00
        t1 < t2: True
Dates:
        d1: 2013-02-17
        d2: 2013-02-18
        d1 > d2: False

日付と時間を組み合わせる

datetime の両方の値を保持するには datetime クラスを使用してください。 date と同様に、その他の共通の値から datetime インスタンスを作成する便利なクラスメソッドがあります。

import datetime

print 'Now    :', datetime.datetime.now()
print 'Today  :', datetime.datetime.today()
print 'UTC Now:', datetime.datetime.utcnow()

d = datetime.datetime.now()
for attr in [ 'year', 'month', 'day', 'hour', 'minute', 'second', 'microsecond']:
    print attr, ':', getattr(d, attr)

予想通り、 datetime インスタンスは datetime オブジェクトの全ての属性をもちます。

$ python datetime_datetime.py
Now    : 2013-02-17 11:32:21.977991
Today  : 2013-02-17 11:32:21.978808
UTC Now: 2013-02-17 16:32:21.978823
year : 2013
month : 2
day : 17
hour : 11
minute : 32
second : 21
microsecond : 979096

date と同様に、 datetime は、新たなインスタンスを作成する便利なクラスメソッドを提供します。 fromordinal()fromtimestamp() もあります。さらに combine() は、既に datetime インスタンスがあって datetime を作成したいときに便利です。

import datetime

t = datetime.time(1, 2, 3)
print 't :', t

d = datetime.date.today()
print 'd :', d

dt = datetime.datetime.combine(d, t)
print 'dt:', dt
$ python datetime_datetime_combine.py
t : 01:02:03
d : 2013-02-17
dt: 2013-02-17 01:02:03

フォーマットと解析

datetime オブジェクトのデフォルトの文字列表現は、 ISO 8601 フォーマット (YYYY-MM-DDTHH:MM:SS.mmmmmm) を使用します。 strftime() を使用して別のフォーマットも生成できます。同様に、入力データが time.strptime() で解析できるタイムスタンプをもつ場合、 datetime.strptime() はそのタイムスタンプを datetime インスタンスに変換するのに便利です。

import datetime

format = "%a %b %d %H:%M:%S %Y"

today = datetime.datetime.today()
print 'ISO     :', today

s = today.strftime(format)
print 'strftime:', s

d = datetime.datetime.strptime(s, format)
print 'strptime:', d.strftime(format)
$ python datetime_datetime_strptime.py
ISO     : 2013-02-17 11:32:22.027173
strftime: Sun Feb 17 11:32:22 2013
strptime: Sun Feb 17 11:32:22 2013

タイムゾーン

datetime モジュールの内部で、タイムゾーンは tzinfo のサブクラスで表されます。 tzinfo は抽象ベースクラスなので、サブクラスを定義して便利なメソッドをもつ適切な実装を提供する必要があります。標準ライブラリドキュメントではサンプル実装が提供されていますが、残念ながら datetime 内には実際の実装は含まれていません。独自クラスの作成に関する詳細と DST 対応クラスと同様に固定長のオフセットを使用するサンプルについては、標準ライブラリドキュメントを参照してください。 pytz もタイムゾーンの実装の詳細を調べるのに良い情報源です。

See also

datetime
本モジュールの標準ライブラリドキュメント
calendar
calendar モジュール
time
time モジュール
dateutil
Labix の datetime を機能拡張する dateutil モジュール
WikiPedia: Proleptic Gregorian calendar
グレゴリアンカレンダシステムの説明
pytz
世界のタイムゾーンデータベース
ISO 8601
日付と時間の数値表現の標準規格
Bookmark and Share