Q1「3 日後」を計算する ときに使うのはどの組み合わせですか?
datetime と time — 日付・時刻・経過時間の扱い方
Python の datetime / time / calendar モジュールを基礎から解説します。date と datetime と timedelta による日付計算、strftime / strptime による文字列変換、time.perf_counter での経過時間計測まで、ハンズオンで学べます。
日付・時刻・経過時間 を扱う 3 つの標準ライブラリ — datetime / time / calendar を整理します。date / datetime / timedelta による日付計算、strftime / strptime での文字列との相互変換、time.perf_counter での経過時間計測までを順に見ていきます。
date / datetime / timedelta — 日付の作成と差の計算
Python で日付を扱うときは datetime モジュールにある 3 つのクラス を使い分けます。date は年月日だけ、datetime は年月日 + 時分秒、そして timedelta は 「3 日間」「2 時間」のような期間 を表します。date + timedelta で「3 日後」が計算でき、date - date で 2 つの日付の差 が timedelta として返ってくる、という対称な設計になっています。
| クラス | 持つ情報 | 代表的な使いどころ |
|---|---|---|
| date | 年・月・日 | 誕生日、注文日など日付だけが意味を持つもの |
| datetime | 年月日 + 時・分・秒 | ログ・ファイル更新日時など時刻まで必要なもの |
| timedelta | 日数 / 秒数 / マイクロ秒 | 「3 日後」「経過時間」など期間を表す |
| time | 時・分・秒(日付なし) | 「営業時間 9:00〜18:00」のような時刻のみ |
date2 - date1 で timedelta が返る。from datetime import date, datetime, timedelta
# 日付の作成
order_date = date(2024, 3, 15)
print(order_date) # 2024-03-15
# 3 日後を計算
delivery = order_date + timedelta(days=3)
print(delivery) # 2024-03-18
# 2 つの date の差は timedelta
elapsed = delivery - order_date
print(elapsed.days) # 3
# 現在時刻
now = datetime.now()
print(now.year, now.month, now.day)
datetime.now と環境依存性
datetime.now() は 動かしているマシンの現在時刻 を返すので、ブラウザの Pyodide ランタイムでも実機でも、実行ごとに値が変わります。演習では値が固定の date(2024, 3, 15) を使い、now() の動作確認は別途コンソールで個別に試すと比較しやすいです。
2 つの日付の差を求める
date 同士の引き算 は timedelta オブジェクトを返します。.days 属性で 日数だけ を取り出せるので、「あと何日?」のような質問に対する整数値が得られます。
strftime / strptime — 日付と文字列の相互変換
ファイルやログ・JSON に含まれる日付は 文字列 で渡されることがほとんどです。Python では strftime(format time) で datetime → 文字列、strptime(parse time) で 文字列 → datetime に変換します。両方とも 書式コード を指定して、%Y が 4 桁年、%m が 2 桁月、というように 記号と意味を対応 させます。
%Y, %m, %d 等)は両方で同じものを使う。| 書式コード | 意味 | 例 |
|---|---|---|
| %Y | 4 桁の年 | 2024 |
| %m | 2 桁の月 (01-12) | 03 |
| %d | 2 桁の日 (01-31) | 15 |
| %H | 2 桁の時 24 時間 (00-23) | 14 |
| %M | 2 桁の分 (00-59) | 30 |
| %S | 2 桁の秒 (00-59) | 00 |
| %A | 曜日名 (英語) | Friday |
| %w | 曜日 (0=Sun, 6=Sat) | 5 |
from datetime import datetime
# 文字列 → datetime
text = "2024-03-15 14:30:00"
dt = datetime.strptime(text, "%Y-%m-%d %H:%M:%S")
print(dt.year, dt.month, dt.day) # 2024 3 15
# datetime → 文字列
dt2 = datetime(2024, 3, 15, 14, 30)
print(dt2.strftime("%Y/%m/%d")) # 2024/03/15
print(dt2.strftime("%Y年%m月%d日 %H:%M")) # 2024年03月15日 14:30
書式不一致は ValueError になる
strptime("2024/03/15", "%Y-%m-%d") のように 文字列の区切り と 書式コード がズレると ValueError で落ちます。入力データの実際の書式 をよく見て、ハイフンならハイフン、スラッシュならスラッシュで揃えること。年月日とコロン区切りの時刻が混ざる "2024-03-15T14:30:00" のような ISO 形式を扱うときは datetime.fromisoformat(text) のほうが楽です。
time と calendar — 経過時間の計測と月情報
time モジュールは datetime とは別 で、より低レベルな時刻 API を提供します。よく使うのは time.perf_counter() で、これは 「現在の経過時間(秒、float)」 を返す高精度カウンタです。処理の前後で 2 回呼んで差を取れば 実行時間が測れます。一方 calendar モジュールは その月が何日まであるか や 月初の曜日 といった カレンダー情報 を取り出すのに使います。
| 関数 | 返す値 | 用途 |
|---|---|---|
| time.time() | Unix 時刻 (float) | 現在時刻のタイムスタンプ |
| time.perf_counter() | 単調増加カウンタ (float, 秒) | 実行時間の計測 |
| calendar.monthrange(y, m) | (月初の曜日, 月末の日) のタプル | 月のカレンダー情報 |
| calendar.isleap(y) | True / False | うるう年か判定 |
import time
import calendar
# 実行時間の計測
start = time.perf_counter()
total = sum(range(100000))
elapsed = time.perf_counter() - start
print("合計:", total)
print("型:", type(elapsed).__name__) # float
# カレンダー情報
weekday, last_day = calendar.monthrange(2024, 2) # (月初の曜日, 月末の日)
print("2024年2月の月末:", last_day, "日")
print("うるう年:", calendar.isleap(2024))
time.time ではなく perf_counter を使う理由
time.time() は Unix 時刻(秒の小数)を返しますが、マシンの時計が NTP で巻き戻ると差がマイナスになる ことがあります。time.perf_counter() は 単調増加(ずっと増え続ける) が保証されていて、経過時間の計測に専用設計 なので、ストップウォッチ用途では常にこちらを選びます。
time.sleep — 一定時間待つ
`time.sleep(秒数)` は 指定した秒数だけプログラムの実行を止める 関数です。リトライ間隔・レート制限・アニメーション制御などで頻出します。引数は float なので time.sleep(0.5) のような小数も渡せます。本演習はブラウザ上で動かすため、長時間の sleep は避けて 0〜1 秒程度で挙動を確認します。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2文字列 "2024/03/15" を datetime に変換するときに使う書式はどれですか?
Q3実行時間の計測 に最も向いているのはどれですか?
Q4ISO 8601 形式の文字列 "2024-03-15T14:30:00" を datetime にする最も簡単な書き方はどれですか?