日付と時刻

日付と時刻の処理はプログラミングで最も一般的なタスクの 1 つです——ログのタイムスタンプ記録、貸出日数の計算、期間ごとのデータ集計……datetime モジュールは Python で日付と時刻を扱う標準的な方法です。


1. 現在時刻の取得

PYTHON
from datetime import datetime, date, time

# 現在の日時
now = datetime.now()
print(now)                      # 2026-06-23 16:00:00.123456

# 現在の日付
today = date.today()
print(today)                    # 2026-06-23

# 特定の日時を作成
d = datetime(2026, 6, 23, 15, 30, 0)
print(d)                        # 2026-06-23 15:30:00

例:誕生日リマインダー(難易度 ⭐)

PYTHON
from datetime import datetime

def days_to_birthday(birth_str):
    """次の誕生日までの日数を計算"""
    today = datetime.now()
    birth = datetime.strptime(birth_str, "%m-%d")
    birthday_this_year = birth.replace(year=today.year)

    if birthday_this_year < today:
        birthday_this_year = birthday_this_year.replace(year=today.year + 1)

    delta = birthday_this_year - today
    return delta.days

print(f"Days until next birthday: {days_to_birthday('12-25')}")
▶ 試してみよう

2. フォーマットとパース

PYTHON
from datetime import datetime

# 日付 → 文字列(フォーマット)
now = datetime.now()
print(now.strftime("%Y-%m-%d"))              # 2026-06-23
print(now.strftime("%Y-%m-%d"))              # 2026-06-23
print(now.strftime("%H:%M:%S"))              # 16:00:00
print(now.strftime("%A"))                    # Tuesday

# 文字列 → 日付(パース)
date_str = "2026-06-23 15:30:00"
parsed = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(parsed)                                # 2026-06-23 15:30:00
フォーマットコード 意味
%Y 4 桁の年 2026
%m 2 桁の月 06
%d 2 桁の日 23
%H 時(24 時間) 15
%M 30
%S 00
%A 曜日の完全な名前 Tuesday
💡 strftime は「日付→文字列」、strptime は「文字列→日付」です。 「f」= format(出力)、「p」= parse(入力)と覚えましょう。


3. timedelta:時間差

PYTHON
from datetime import datetime, timedelta

now = datetime.now()

# 未来/過去の時刻を計算
future = now + timedelta(days=7)
past = now - timedelta(days=30)

print(f"In 7 days: {future.strftime('%Y-%m-%d')}")
print(f"30 days ago: {past.strftime('%Y-%m-%d')}")

# 時間計算
print(timedelta(days=7))                     # 7 days, 0:00:00
print(timedelta(hours=3, minutes=15))        # 3:15:00
print(timedelta(weeks=2))                    # 14 days, 0:00:00

# 2 つの日付の差
d1 = datetime(2026, 6, 1)
d2 = datetime(2026, 6, 23)
diff = d2 - d1
print(f"Difference: {diff.days} days")       # Difference: 22 days

例:サブスクリプション期限切れリマインダー(難易度 ⭐⭐)

PYTHON
from datetime import datetime, timedelta

# ユーザーサブスクリプション情報をシミュレート
subscriptions = [
    {"name": "Zhang San", "expire": "2026-07-15"},
    {"name": "Li Si", "expire": "2026-06-25"},
    {"name": "Wang Wu", "expire": "2026-08-01"},
    {"name": "Zhao Liu", "expire": "2026-06-20"},
]

today = datetime.now().strftime("%Y-%m-%d")
today = datetime.strptime(today, "%Y-%m-%d")

print("=== Subscription Expiry Check ===")
for sub in subscriptions:
    expire = datetime.strptime(sub["expire"], "%Y-%m-%d")
    remaining = (expire - today).days

    if remaining < 0:
        print(f"Expired ({sub['name']}): {-remaining} days ago")
    elif remaining <= 7:
        print(f"Expiring soon ({sub['name']}): {remaining} days left")
    else:
        print(f"Active ({sub['name']}): {remaining} days left")
▶ 試してみよう

よくあるユースケース


❓ よくある質問

Q datetime.now() はローカル時刻と UTC 時刻のどちらを返しますか?
A ローカル時刻です。UTC を取得するには datetime.utcnow() を使用します。ただし、utcnow() はタイムゾーン情報のないナイーブな datetime を返します。本番環境では、datetime.now(timezone.utc) または pytzzoneinfo で適切なタイムゾーン処理を行ってください。
Q strptime のパースに失敗した場合はどうなりますか?
A ValueError が発生します——「time data 'xxx' does not match format '%Y-%m-%d'」。エラー処理には try-except で囲みます。よくある落とし穴:月と日は 2 桁である必要があります(%m"6" にマッチせず、"06" が必要です)。
Q timedelta でサポートされる最大日数は?
A 理論上は上限がありません——timedelta(days=1000000) も有効です。ただし、total_seconds() はオーバーフローする可能性があります。日常的な使用では範囲は問題になりません。

📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐):現在時刻を以下の形式で出力してください:2026-06-23 Tuesday2026-06-23 16:0006/23/2026

  2. 中級(難易度 ⭐⭐):関数 workdays_between(start, end) を書いてください。2 つの日付間の平日(月曜から金曜)の日数を計算します。ヒント: timedelta で毎日を反復。weekday() で曜日を確認(0=月曜、4=金曜)。

  3. 上級(難易度 ⭐⭐⭐):「ポモドーロタイマー」を書いてください。25 分作業 → 5 分休憩、4 回ループ、その後 15 分の長い休憩。タイミングには time.sleep()、現在のフェーズと残り時間の表示には datetime を使用。

100%