10.4 カレンダーとクロック
プログラミングにおいて、日付と時刻の処理は驚くほど厄介です。うるう年の計算や、地域ごとの標準時の違い、そしてサマータイム(Daylight Saving Time)など、多くの複雑な要素が絡み合っているからです。
Pythonの標準ライブラリには、これらの問題を処理するための複数のモジュール(datetime、time、calendar など)が用意されています。
10.4.1 datetime モジュール
Section titled “10.4.1 datetime モジュール”datetime モジュールは、日付や時刻を扱うための4つのメインオブジェクトを提供しています。
1. date オブジェクト(年月日)
Section titled “1. date オブジェクト(年月日)”年、月、日を指定して作成します。
from datetime import date
# 2014年のハロウィンhalloween = date(2014, 10, 31)print(halloween.day) # 31print(halloween.month) # 10print(halloween.year) # 2014
# ISO 8601形式(YYYY-MM-DD)の文字列で出力print(halloween.isoformat()) # '2014-10-31'
# 今日の日付を取得now = date.today()print(now) # 出力例: datetime.date(2014, 2, 2)2. timedelta オブジェクト(日時の間隔)
Section titled “2. timedelta オブジェクト(日時の間隔)”日付の足し算や引き算を行うために使います。
from datetime import timedelta
one_day = timedelta(days=1)
# 今日の日付に1日を足して明日を計算tomorrow = now + one_dayprint(tomorrow) # datetime.date(2014, 2, 3)
# 17日後を計算print(now + 17 * one_day) # datetime.date(2014, 2, 19)3. time オブジェクト(時分秒とマイクロ秒)
Section titled “3. time オブジェクト(時分秒とマイクロ秒)”1日のなかの特定の時刻を表現します。
from datetime import time
# 正午(12時0分0秒)noon = time(12, 0, 0)print(noon.hour) # 12print(noon.minute) # 04. datetime オブジェクト(日付と時刻の両方)
Section titled “4. datetime オブジェクト(日付と時刻の両方)”日付と時刻の両方を保持します。date と time を結合して作ることもできます。
from datetime import datetime
# 現在の日付と時刻を取得now_dt = datetime.now()print(now_dt)# 出力例: datetime.datetime(2014, 2, 2, 23, 15, 34, 694988)
# dateとtimeを結合するnoon_today = datetime.combine(now, noon)print(noon_today) # datetime.datetime(2014, 2, 2, 12, 0)
# datetimeからdateやtimeを抽出するprint(noon_today.date()) # datetime.date(2014, 2, 2)print(noon_today.time()) # datetime.time(12, 0)10.4.2 time モジュール
Section titled “10.4.2 time モジュール”datetime モジュール内の time オブジェクトとは別に、標準ライブラリには time というモジュールも存在します。これは主にUnix時間(1970年1月1日午前0時からの経過秒数、エポックタイム)を扱うために使われます。
import time
# 現在のUnix時間(秒数)を取得now_unix = time.time()print(now_unix) # 出力例: 1391488263.664645
# Unix時間を文字列に変換print(time.ctime(now_unix)) # 'Mon Feb 3 22:31:03 2014'struct_time オブジェクト
Section titled “struct_time オブジェクト”Unix時間を、年月日時分秒に分かれた struct_time オブジェクトに変換できます。
# システムのローカルタイムに変換tm_local = time.localtime(now_unix)print(tm_local)
# UTC(協定世界時)に変換tm_utc = time.gmtime(now_unix)
# struct_time を Unix時間に戻すprint(time.mktime(tm_local))10.4.3 日時の読み書き(文字列フォーマット)
Section titled “10.4.3 日時の読み書き(文字列フォーマット)”日時オブジェクトと文字列を相互に変換するには、書式指定子(%Y, %m, %d, %H, %M, %S など)を使います。
strftime(): 日時オブジェクト $\rightarrow$ 文字列strptime(): 文字列 $\rightarrow$ 日時オブジェクト
import time
# 書式指定文字列の定義fmt = "It's %A %B %d, %Y, local time %I:%M:%S%p"t = time.localtime()
# struct_time を文字列に変換print(time.strftime(fmt, t))# 出力例: "It's Tuesday, February 04, 2014, local time 07:28:38PM"
# 文字列を struct_time に変換(書式が完全に一致している必要があります)fmt_short = "%Y-%m-%d"parsed_time = time.strptime("2012-01-29", fmt_short)print(parsed_time.tm_year, parsed_time.tm_mon, parsed_time.tm_mday) # 2012 1 29ロケールの変更
Section titled “ロケールの変更”locale モジュールを使うと、システム設定に依存する月名や曜日名(%A, %B など)を他言語(フランス語やドイツ語など)に変更できます。
import localefrom datetime import date
halloween = date(2014, 10, 31)
# フランス語のロケールを設定して出力locale.setlocale(locale.LC_TIME, 'fr_fr')print(halloween.strftime('%A, %B %d'))# 出力: 'Vendredi, octobre 31'10.4.4 代替モジュール
Section titled “10.4.4 代替モジュール”標準ライブラリのモジュールが複雑に感じる場合や、より高度な機能(タイムゾーン処理や柔軟なパースなど)が必要な場合は、サードパーティ製のパッケージが便利です。
代表的なものとして arrow, dateutil, iso8601, fleming などがあります。