操作
第8章 日付と時刻の処理¶
8.1 日付や時刻を扱う datetime¶
datetime モジュールのオブジェクト
| オブジェクト名 | 用途 |
|---|---|
| date | 日付 |
| time | 時刻 |
| datetime | 日時 |
| timedelta | 2つの日時の差 |
-
date オブジェクト
-
date(year, month, day) -
インスタンスメソッド
メソッド名 解説 戻り値 weekday()曜日を返す (月曜日 0, 日曜日 6) int isoweekday()曜日を返す (月曜日 1, 日曜日 7) int isoformat()ISO 8601形式 (YYYY-MM-DD) で表した文字列を返す str strftime(format)指定したフォーマットに従って日付文字列を返す str -
属性
属性名 解説 戻り値 year年 int month月 int day日 int -
クラスメソッド
メソッド名 解説 戻り値 today()今日の日付の date オブジェクトを返す datetime.date fromisoformat(date_string)ISO 8601形式 (YYYY-MM-DD) で表した日付文字列から date オブジェクトを生成する datetime.date
>>> from datetime import date >>> today = date.today() >>> today datetime.date(2025, 7, 2) >>> birthday = date(1983, 9, 28) >>> birthday datetime.date(1983, 9, 28) >>> today.isoweekday() 3 >>> today.isoformat() '2025-07-02' >>> tomorrow = date.fromisoformat('2025-07-03') >>> tomorrow.day 3 >>> tomorrow.isoweekday() 4 >>> tomorrow.strftime("明日は西暦 %Y 年 %m 月 %d 日 (%a) です") '明日は西暦 2025 年 07 月 03 日 (Thu) です' -
-
time オブジェクト
-
time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) -
インスタンスメソッド
メソッド名 解説 戻り値 isoformat(timespec='auto')ISO 8601 形式 (HH:MM:SS.ffffff) の文字列を返す
マイクロ秒が 0 の場合は HH:MM:SS
(*1)str strftime(format)(略) str tzname()タイムゾーン名 str - (*1)
timespec: 大きいほうからどこまで表示するかを指定する (非表示部分は切り捨て)-
hoursHH -
minutesHH:MM -
secondsHH:MM:SS -
millisecondsHH:MM:SS.sss -
microsecondsHH:MM:SS.mmmmmm -
auto: microsecond が 0 ならseconds、そうでない場合microseconds
-
- (*1)
-
属性
属性名 解説 戻り値 hour時 int minute分 int second秒 int microsecondマイクロ秒 int tzinfoタイムゾーン情報 オブジェクト fold(略) 0 または 1 int -
クラスメソッド
メソッド名 解説 戻り値 fromisoformat(time_string)ISO 8601 形式 (HH:MM:SS.ffffff または HH:MM:SS) の文字列から time オブジェクトを生成 datetime.time
>>> from datetime import time >>> t1 = time.fromisoformat("21:54:12.345678") >>> t1 datetime.time(21, 54, 12, 345678) >>> t1.isoformat() '21:54:12.345678' >>> t1.hour 21 >>> t1.second 12 >>> t1.strftime("今は %H 時 %M 分 %S 秒 です") '今は 21 時 54 分 12 秒 です' -
-
datetime オブジェクト
-
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) -
インスタンスメソッド
メソッド名 解説 戻り値 date()同じ年月日の date を返す datetime.date time()同じ時分秒の time を返す datetime.time isoformat(sep='T', timespec='auto')sepは 1 文字で、日付と時刻の間に配置される
他は date, time の同メソッド参照str strftime(format)(略) str tzname()(略) str -
属性
- date, time と同じ
-
yearmonthdayhourminutesecondmicrosecondtzinfofold
-
クラスメソッド
メソッド名 解説 戻り値 today()デフォルトタイムゾーンの現在日時を表す datetime を返す
※「today」だが、時刻も設定されるdatetime.datetime now(tz=None)today()と同様だが、tzに zoneinfo.ZoneInfo オブジェクトを渡せばタイムゾーンを指定可能datetime.datetime utcnow()UTC の現在日時を表す datetime を返す datetime.datetime fromisoformat(date_string)ISO 8601 形式 (YYYY-MM-DDTHH:MM:SS.ffffff) の文字列から datetime を生成 datetime.datetime strptime(date_string, format)指定したフォーマットに従って文字列から datetime オブジェクトを生成 datetime.datetime
-
-
timedelta オブジェクト
date, time, datetime の差を扱うオブジェクトtimedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)- date, time, datetime の差演算結果は timedelta オブジェクトとして返る
from datetime import date, timedelta >>> today = date.today() >>> today datetime.date(2025, 7, 2) >>> birthday = date(1983, 9, 28) >>> delta = today - birthday >>> delta.days / 365 41.78904109589041 -
strftime() での指定子
代表的なもの指定子 意味 使用例 %d 0 埋めした月中の日にち 01,02,...,31 %m 0 埋めした月 01,02,...,12 %y 0 埋めした西暦下2桁 00,01,...,99 %Y 0 埋めした西暦4桁 0001,0002,...,9999 %H 0 埋めした時 (24時間表記) 00,01,...,23 %M 0 埋めした分 00,01,...,59 %S 0 埋めした秒 00,01,...,59 -
パースエラー
-
fromisoformat()strptime()でパースできない文字列を渡すと、ValueError が発生する
-
8.2 時刻を扱う time¶
time モジュールはエポック (epoch) という基準時刻からの経過時間 (エポック秒) を扱う. 通常エポックは 1970年1月1日0時0分0秒
-
主な関数
関数名 解説 戻り値 gmtime([secs])UTC の現在時刻を表す struct_time を返す
secs が指定された場合はエポック秒 secs として扱うtime.struct_time localtime([secs])ローカルの現在時刻を表す struct_time を返す
secs が指定された場合はエポック秒 secs として扱うtime.struct_time strftime(format[, t])t(time.struct_time) を指定されたフォーマットに従った文字列として返すtが指定されない場合は localtime() の値を使用str time()エポックからの秒数を返す float >>> import time >>> time.gmtime() time.struct_time(tm_year=2025, tm_mon=7, tm_mday=2, tm_hour=14, tm_min=13, tm_sec=21, tm_wday=2, tm_yday=183, tm_isdst=0) >>> time.localtime() time.struct_time(tm_year=2025, tm_mon=7, tm_mday=2, tm_hour=23, tm_min=13, tm_sec=30, tm_wday=2, tm_yday=183, tm_isdst=0) >>> time.strftime("日本は %H:%M:%S") '日本は 23:14:34' >>> time.time() 1751465685.0863643 -
時刻オブジェクト struct_time
- struct_time は名前付きタプル
インデックス 属性名 解説 戻り値 0 tm_year 年 int 1 tm_mon 月 int 2 tm_mday 日 int 3 tm_hour 時 int 4 tm_min 分 int 5 tm_sec 秒 int 6 tm_wday 曜日 (0:月曜日) int 7 tm_yday 年の中での日 (1 - 366) int 8 tm_isdst 夏時間かどうか (0:夏時間ではない) int tm_zone タイムゾーン名 str tm_gmtoff タイムゾーンの UTC からのオフセット秒 int >>> jtime = time.localtime() >>> jtime time.struct_time(tm_year=2025, tm_mon=7, tm_mday=2, tm_hour=23, tm_min=16, tm_sec=33, tm_wday=2, tm_yday=183, tm_isdst=0) >>> jtime[0] 2025 >>> jtime.tm_hour 23 >>> jtime.tm_sec 33 -
スレッドの一時停止 sleep()
-
time モジュール使用例
- 処理失敗時のリトライ時に sleep() で待機
- datetime と組み合わせて日時計算
- 計測対象の処理前後で現在時刻取得をして、簡易処理時間計測
-
time.sleep() と async/await 構文は意図通りに動作しない可能性あり
- async/await は 19.1 (p.446)
8.3 IANA タイムゾーンデータベースを扱う zoneinfo¶
- ZoneInfo オブジェクト
-
ZoneInfo(key)-
keyタイムゾーン名
>>> from zoneinfo import ZoneInfo >>> TOKYO = ZoneInfo('Asia/Tokyo') Traceback (most recent call last): File "C:\Python313\Lib\zoneinfo\_common.py", line 12, in load_tzdata return resources.files(package_name).joinpath(resource_name).open("rb") ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^ File "C:\Python313\Lib\importlib\resources\_common.py", line 46, in wrapper return func(anchor) File "C:\Python313\Lib\importlib\resources\_common.py", line 56, in files return from_package(resolve(anchor)) ~~~~~~~^^^^^^^^ File "C:\Python313\Lib\functools.py", line 934, in wrapper return dispatch(args[0].__class__)(*args, **kw) ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "C:\Python313\Lib\importlib\resources\_common.py", line 82, in _ return importlib.import_module(cand) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^ File "C:\Python313\Lib\importlib\__init__.py", line 88, in import_module return _bootstrap._gcd_import(name[level:], package, level) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked ModuleNotFoundError: No module named 'tzdata' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<python-input-1>", line 1, in <module> TOKYO = ZoneInfo('Asia/Tokyo') File "C:\Python313\Lib\zoneinfo\_common.py", line 24, in load_tzdata raise ZoneInfoNotFoundError(f"No time zone found with key {key}") zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key Asia/Tokyo'- Windows では上記の様にエラーが出る (OS の タイムゾーンデータベースの形式が TZif でない為)
- tzdata パッケージをインストールすれば解決する
pip install tzdata
>>> from zoneinfo import ZoneInfo >>> TOKYO = ZoneInfo('Asia/Tokyo') >>> TOKYO zoneinfo.ZoneInfo(key='Asia/Tokyo') >>> from datetime import datetime >>> dt = datetime(1983, 9, 28, tzinfo=TOKYO) >>> dt datetime.datetime(1983, 9, 28, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Tokyo')) >>> dt.astimezone(ZoneInfo('America/Los_Angeles') ... ) datetime.datetime(1983, 9, 27, 8, 0, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))
-
-
8.4 datetime の強力な拡張モジュール dateutil¶
- インストール
pip install python-dateutil
日付文字列の構文解析 parser¶
-
parser.parse(timestr, parserinfo=None, **kwargs)(戻り値: datetime.datetime)-
timestr日時文字列 -
parserinfo日付解析の振る舞いを変更するためのオブジェクト -
**kwargs-
default変換するときのデフォルト値となる datetime オブジェクト -
dayfirstTrue を指定すると "1/2/3" などの先頭を「日」として解析する -
yearfirstTrue を指定すると "1/2/3" などの先頭を「年」として解析する
-
>>> from dateutil.parser import parse >>> parse("2025/7/3 21:54") datetime.datetime(2025, 7, 3, 21, 54) >>> parse("1/2/3") datetime.datetime(2003, 1, 2, 0, 0) # 指定無しは 月/日/年 と解析 >>> parse("1/2/3", dayfirst=True) datetime.datetime(2003, 2, 1, 0, 0) # 日/月/年 と解析 >>> parse("1/2/3", yearfirst=True) datetime.datetime(2001, 2, 3, 0, 0) # 年/月/日 と解析 >>> from datetime import datetime >>> default_dt = datetime.today() >>> default_dt datetime.datetime(2025, 7, 3, 21, 57, 47, 441323) # デフォルトを 2025-07-03 21:57:47 とする >>> parse("12:30:55", default=default_dt) datetime.datetime(2025, 7, 3, 12, 30, 55) # 文字列に無い値はデフォルトの値になる -
日付の差の計算 relativedelta¶
-
relativedelta.relativedelta(引数下記)- date または datetime を 2 つ渡すと、その差を relativedelta として生成
dt1=Nonedt2=None
- 相対値引数 : 和差演算の際に、増減させる値を指定 (数値の前に
+-を付加)years=0months=0days=0leapdays=0weeks=0hours=0minutes=0seconds=0microseconds=0
- 絶対値引数 : 和差演算の際に、ここで指定した値に置換する (増減ではない)
year=Nonemonth=Noneday=Noneweekday=Noneyearday=Nonenlyearday=Nonehour=Noneminute=Nonesecond=Nonemicrosecond=None
>>> from datetime import datetime, date >>> from dateutil.relativedelta import relativedelta >>> today = date.today() >>> today datetime.date(2025, 7, 3) >>> birthday = date(1983, 9, 28) >>> birthday datetime.date(1983, 9, 28) >>> relativedelta(today, birthday) # 今日と誕生日の差を relativedelta で relativedelta(years=+41, months=+9, days=+5) # 41年9か月と5日 >>> now = datetime.now() >>> now datetime.datetime(2025, 7, 3, 22, 28, 37, 209118) # 2025-07-03 22:28:37 >>> now + relativedelta(days=+3, hours=+1) # 3日と1時間後 datetime.datetime(2025, 7, 6, 23, 28, 37, 209118) # 2025-07-06 23:28:37 >>> now + relativedelta(months=+4, day=20) # 4か月後の20日 datetime.datetime(2025, 11, 20, 22, 28, 37, 209118) # 2025-11-20 22:28:37 >>> now - relativedelta(months=+8, day=20) # 8か月前の20日 datetime.datetime(2024, 11, 20, 22, 28, 37, 209118) # 2024-11-20 22:28:37>>> from datetime import datetime, date >>> from dateutil.relativedelta import relativedelta >>> from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU >>> today = date.today() >>> today datetime.date(2025, 7, 3) >>> today + relativedelta(weekday=SU) # 次の日曜日 datetime.date(2025, 7, 6) >>> today + relativedelta(weekday=SU(-1)) # 前の日曜日 datetime.date(2025, 6, 29) >>> today + relativedelta(yearday=365) # 年の365日目 datetime.date(2025, 12, 31) >>> today + relativedelta(months=+2, day=1, weekday=SA(+3)) # 2か月後の3回目の土曜日 datetime.date(2025, 9, 20) - date または datetime を 2 つ渡すと、その差を relativedelta として生成
繰り返しルール rrule¶
-
rrule.rrule(引数下記)-
freq繰り返し頻度YEARLYMONTHLYWEEKLYDAILYHOURLYMINUTELYSECONDLY -
cache=FalseTrue の場合キャッシュする -
dtstart=None開始日時を datetime で指定、指定無しの場合は datetime.now() の値が使われる -
interval=1間を飛ばす数 (例:HOURLY で interval=2 なら、2時間毎) -
wkst=None週の始まりの曜日 (byweekno を指定した場合に意味を持つようだ) -
count=None繰り返し回数 (until と同時には指定できない) -
until=None終了日時を datetime で指定 (count と同時には指定できない) -
bysetpos=NonebyXXXX で指定したルールに対して、何回目のものを有効とするかを+-の数値で指定 -
bymonthbymonthdaybyweeknobyweekdaybyhourbyminutebysecondbyeaster指定された期間のみを対象とする (フィルタのようなもの). 単一値、またはタプルを指定- 特定月、特定日(毎月25日等)、特定曜日(月曜と木曜等)、特定番号週(年の週番号指定の週) など
>>> from dateutil.rrule import rrule >>> from dateutil.rrule import DAILY, WEEKLY, MONTHLY >>> from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU >>> import pprint >>> import sys >>> sys.displayhook = pprint.pprint # 表示を見やすくするために設定 >>> start = datetime(2021, 2, 16) >>> list(rrule(DAILY, count=3, dtstart=start)) # 指定日から3日間 [datetime.datetime(2021, 2, 16, 0, 0), datetime.datetime(2021, 2, 17, 0, 0), datetime.datetime(2021, 2, 18, 0, 0)] >>> list(rrule(DAILY, dtstart=start, until=datetime(2021, 2, 19))) # 指定期間毎日 [datetime.datetime(2021, 2, 16, 0, 0), datetime.datetime(2021, 2, 17, 0, 0), datetime.datetime(2021, 2, 18, 0, 0), datetime.datetime(2021, 2, 19, 0, 0)] >>> list(rrule(WEEKLY, count=4, wkst=SU, byweekday=(TU,TH), dtstart=start)) # 毎週火曜、木曜 [datetime.datetime(2021, 2, 16, 0, 0), datetime.datetime(2021, 2, 18, 0, 0), datetime.datetime(2021, 2, 23, 0, 0), datetime.datetime(2021, 2, 25, 0, 0)] >>> list(rrule(MONTHLY, count=3, byweekday=FR(-1), dtstart=start)) # 毎月最終金曜日 [datetime.datetime(2021, 2, 26, 0, 0), datetime.datetime(2021, 3, 26, 0, 0), datetime.datetime(2021, 4, 30, 0, 0)] -
Tatsuya ISHIGAKI さんが5ヶ月前に更新 · 1件の履歴