DATETIME CHEATSHEET

Python 日付フォーマット・日時計算チートシート

「今日の日付がほしい」「文字列を日付に変えたい」「30日後を出したい」——目的から引ける逆引き表です。コードはすべて Python 3.12.10 で実行し、出力をそのまま載せています。

🎯 対象: 日付処理を毎回検索している初心者〜初級者 ⏱️ 読了: 約11分 🐍 検証: Python 3.12.10 / Windows 11

結論:日付だけなら date、時刻も要るなら datetime、期間は timedelta。文字列にするのが strftime、文字列から読むのが strptime。この4つが分かれば日付処理の大半は片づきます。早見表から必要な行へ飛んでください。

1. 逆引き早見表

よく使う順です。「結果」は 2026-09-20 に Python 3.12.10 で実行した出力(現在時刻の行は毎回変わります)。

やりたいこと書くコード結果
今日の日付date.today()2026-09-20
今の日時datetime.now()2026-09-20 22:55:34.353069
今のUTC時刻datetime.now(timezone.utc)2026-09-20 13:55:34.353069+00:00
日付 → 文字列d.strftime("%Y/%m/%d")2026/09/20
文字列 → 日時datetime.strptime(s, "%Y/%m/%d")2026-09-20 00:00:00
ISO文字列 → 日付date.fromisoformat("2026-09-20")2026-09-20
30日後d + timedelta(days=30)2026-10-20
2つの日付の差(日数)(d2 - d1).days102
その月の日数(末日)calendar.monthrange(2026, 9)[1]30
曜日(月=0〜日=6)d.weekday()6
うるう年かどうかcalendar.isleap(2028)True
日本時間つきの現在時刻datetime.now(ZoneInfo("Asia/Tokyo"))2026-09-20 22:55:34.353069+09:00
Excelのシリアル値 → 日時datetime(1899, 12, 30) + timedelta(days=45000)2023-03-15 00:00:00

import は from datetime import datetime, date, timedelta, timezoneimport calendarfrom zoneinfo import ZoneInfo の3行。すべて標準ライブラリですが、タイムゾーンだけ Windows に例外があります(7章)。

2. date・datetime・time・timedelta の違い

datetimeモジュール名でもクラス名でもあるため、from datetime import datetime という import になります。

持っている情報使いどころ
date年・月・日誕生日・締切日・家計簿。時刻が不要なときの既定
datetime年月日+時分秒+マイクロ秒ログの記録時刻・予約時刻・計測の開始と終了
time時分秒だけ(日付なし)「毎日9:00」のような時刻だけの設定値
timedelta期間(日・秒・マイクロ秒)N日後の計算・2点間の差・タイマーの残り

関係は「日付 − 日付 = 期間」「日付 + 期間 = 日付」の2本だけ。import timetime モジュールは datetime.time とは別物で、待機や経過秒の計測は前者が担当します。

3. 今日の日付と現在時刻(utcnow は非推奨)

from datetime import datetime, date, timezone

print(datetime.now())              # 例: 2026-09-20 23:58:12.345678
print(date.today())                # 例: 2026-09-20
print(datetime.now(timezone.utc))  # 例: 2026-09-20 14:58:12.345678+00:00

マイクロ秒が邪魔なら .replace(microsecond=0) を付けます。古い記事で見る datetime.utcnow()3.12 で非推奨になりました。

datetime.utcnow()           # 3.12 以降は DeprecationWarning が出る
datetime.now(timezone.utc)  # 置き換え先(UTC だと分かる値が返る)
⚠️
実際に出る警告(3.12.10 で確認)

DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).

返り値が「UTCなのにUTCだという情報を持たない」ためです。astimezone() に渡すとローカル時刻と解釈され、時差の分ずれます。3.14.7 でも警告のまま残っていました。

4. 文字列 ⇄ 日付の変換

f が format(日付→文字列)、p が parse(文字列→日付)と覚えると取り違えが減ります。

日付 → 文字列(strftime)

d = datetime(2026, 9, 20, 7, 5, 3)

print(d.strftime("%Y-%m-%d %H:%M:%S"))  # → 2026-09-20 07:05:03
print(d.strftime("%Y年%m月%d日"))         # → 2026年09月20日
print(d.strftime("%#m/%#d"))            # → 9/20(Windows。Linux・macOS は %-m/%-d)

ゼロ埋めを外す書き方はOSで違います。Windows は %#m、Linux・macOS は %-m(Windows で %-mValueError: Invalid format string)。配布するなら f"{d.month}/{d.day}" が安全です。

文字列 → 日時(strptime)

s = "2026/09/20 07:05"

print(datetime.strptime(s, "%Y/%m/%d %H:%M"))         # → 2026-09-20 07:05:00
print(datetime.strptime(s, "%Y/%m/%d %H:%M").date())  # → 2026-09-20

strptimedatetime を返すので、日付だけ要るなら .date() を付けます。書式が1文字でも違うとエラーです(8章)。

ISO 8601 形式なら書式指定は不要

ISO 8601 形式は、書式を書かずに読めます。

print(date.fromisoformat("2026-09-20"))                     # → 2026-09-20
print(datetime.fromisoformat("2026-09-20T07:05:03+09:00"))  # → 2026-09-20 07:05:03+09:00
print(datetime(2026, 9, 20, 7, 5, 3).isoformat())           # → 2026-09-20T07:05:03

3.11 で守備範囲が広がり、末尾の Z(UTCの意味)や区切りなしの 20260920 も読めます。3.12.10 では 2026-09-20T07:05:03Z2026-09-20 07:05:03+00:00 でした。CSVやJSONの日付列は、まず fromisoformat を試すのが近道です。

5. 書式コード早見表

よく使う15個です。出力は datetime(2026, 9, 20, 7, 5, 3, 123456)ZoneInfo("Asia/Tokyo") を付けて通した結果。

コード意味出力
%Y / %y西暦4桁 / 下2桁2026 / 26
%m / %d月 / 日(ゼロ埋め2桁)09 / 20
%H / %M / %S時(24時間制)/ 分 / 秒07 / 05 / 03
%fマイクロ秒(6桁)123456
%a / %A曜日の略称 / 正式名Sun / Sunday
%b / %B月の略称 / 正式名Sep / September
%j年始からの通算日263
%z / %ZUTCとの時差 / タイムゾーン名+0900 / JST

組むと d.strftime("%Y/%m/%d(%a) %H時%M分")2026/09/20(Sun) 07時05分曜日や月名が英語なのは strftime が既定でCロケールを使うためで、日本語にするならロケール設定より "月火水木金土日"[d.weekday()] と自分で当てるほうがぶれません(6章)。和暦は標準では扱えません。

6. 日付の計算(N日後・差分・月末・曜日)

N日後と、2つの日付の差

from datetime import timedelta

d = date(2026, 9, 20)
print(d + timedelta(days=30))         # → 2026-10-20
print((date(2026, 12, 31) - d).days)  # → 102

timedelta には weekshoursminutesseconds も渡せます。日数は .days、総秒数は .total_seconds().seconds日を除いた端数の秒なので、総秒数のつもりで使うとずれます。

月末を出す

import calendar

print(calendar.monthrange(2026, 9))                    # → (calendar.TUESDAY, 30)
print(date(2026, 9, calendar.monthrange(2026, 9)[1]))  # → 2026-09-30

monthrange は「1日の曜日」と「日数」を返します。1つめは 3.12 から calendar.Day 列挙型で表示されますが中身は整数です。うるう年も考慮されます。

1か月後(標準ライブラリだけでやる)

timedeltamonths はありません。1か月は28〜31日と長さが変わり、期間として表せないためです。

def add_months(d, n):
    y, m = divmod(d.year * 12 + d.month - 1 + n, 12)
    return date(y, m + 1, min(d.day, calendar.monthrange(y, m + 1)[1]))

print(add_months(date(2026, 1, 31), 1))  # → 2026-02-28(末日で丸める)

1月31日の1か月後を2月28日にするか3月3日にするかは、決めるべき仕様です。python-dateutil なら1行で書けます(pip はインストールと環境構築へ)。

曜日を出す

print(d.weekday(), d.isoweekday())  # → 6 7(月=0・日=6 と 月=1・日=7)
print("月火水木金土日"[d.weekday()])   # → 日

起点が2種類あるのでどちらを使うか統一してください。土日判定は d.weekday() >= 5 が定番です。

N営業日後(祝日は考えない簡易版)

def add_business_days(d, n):
    while n > 0:
        d += timedelta(days=1)
        if d.weekday() < 5:  # 5=土・6=日 は数えない(祝日は判定していない)
            n -= 1
    return d

print(add_business_days(date(2026, 9, 18), 3))  # → 2026-09-23

見ているのは曜日だけです。2026年9月21日〜23日には祝日が含まれるため、祝日まで数えるならこの結果は使えません。内閣府が公開する祝日CSVなどの外部データが要ります。

7. タイムゾーン:naive と aware、zoneinfo

日付処理で最後まで残る難所です。日時には2種類あります。

  • naive: タイムゾーン情報を持たない。datetime.now() が返すのはこちら
  • aware: tzinfo を持ち、UTCとの時差が確定している(公式は utcoffset() が値を返すものと定義)

この2つは混ぜて計算できません。国内で完結する家計簿なら naive、海外の時刻やUTCログを扱うなら aware、と先に決めてください。

zoneinfo で日本時間を扱う

タイムゾーンは 3.9 で標準ライブラリに入った zoneinfo を使います。pytz を勧める記事も残っていますが、新規のコードはこちらです。

from zoneinfo import ZoneInfo

jst = ZoneInfo("Asia/Tokyo")
t = datetime(2026, 9, 20, 22, 0, tzinfo=jst)
print(t)                              # → 2026-09-20 22:00:00+09:00
print(t.astimezone(ZoneInfo("UTC")))  # → 2026-09-20 13:00:00+00:00

名前は "JST" ではなく IANA の識別子 "Asia/Tokyo"astimezone() は時刻そのものを変換します(22:00 JST → 13:00 UTC)。

naive に後から付ける方法は2つあり、意味が違いますreplace(tzinfo=jst) は時刻を動かさずラベルを貼るだけ、astimezone(jst) は「PCのローカル時刻だ」と仮定して変換します。日本時間のPCでは同じ値ですが、UTC設定のサーバーでは後者だけ変わります。明示するだけなら replace です。

Windows では tzdata が要る(実測)

zoneinfo はOSのタイムゾーンデータベースを読みますが、Windows にはそれがありませんzoneinfo.TZPATH は空のタプル ())。データ無しで作ると、こうなります。

⚠️
データが無いPCでの実行結果

zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key Asia/Tokyo'

新しく作った仮想環境(Python 3.12.10 / Windows 11)での実行結果です。名前の綴りより先にデータの有無を疑ってください。

解決策は、公式も案内するフォールバック用パッケージです。

pip install tzdata

同じ環境に入れたところ(tzdata 2026.4)、先ほどのコードが 2026-09-20 22:00:00+09:00 を返しました(TZPATH は空のままです)。Windows 向けに配るなら tzdata も必要なパッケージとして案内します。Linux・macOS はOS側にあります。

8. よくあるエラー5つ

すべて 3.12.10 で実際に起こした文面です。

① 書式が文字列と合っていない

datetime.strptime("2026/09/20", "%Y-%m-%d")
# ValueError: time data '2026/09/20' does not match format '%Y-%m-%d'

区切りが / なのに書式が - です。実データと指定書式が両方出るので1文字ずつ見比べるのが最短。CSV由来なら末尾の改行や全角スペースも疑ってください(s.strip())。読み方はエラー辞典の ValueErrorへ。

② strftime と strptime の取り違え

datetime.strftime("2026-09-20", "%Y")
# TypeError: descriptor 'strftime' for 'datetime.date' objects doesn't apply to a 'str' object

文字列を日付にしたいのに、日付を文字列にする側を呼んでいます。文字列から読むのは strptime(p = parse)。「'str' object」が渡した値の型を教えています。

③ naive と aware を混ぜた

datetime.now() - datetime.now(timezone.utc)
# TypeError: can't subtract offset-naive and offset-aware datetimes

片方だけタイムゾーンを持っています。7章のとおり、どちらかに揃えてから計算します。DBの値とAPIの値を比べるときに起きがちです。

④ 日付に整数を足した

date(2026, 9, 20) + 1
# TypeError: unsupported operand type(s) for +: 'datetime.date' and 'int'

「1日後」は + 1 ではなく + timedelta(days=1)。日付に足せるのは期間だけです。

⑤ 存在しない日になった

date(2026, 1, 31).replace(month=2)
# ValueError: day is out of range for month

2月31日は存在しません。replace で月だけ変えるやり方は月末で壊れます。6章add_months のように末日を丸めてから組み立ててください。

📌
エラーメッセージは版で変わる

⑤の文面は 3.12.10 のものです。3.14.7 では ValueError: day 31 must be in range 1..28 for month 2 in year 2026 と詳しくなりました。検索で見た文面と手元の表示が違っても、原因が別とは限りません。

9. 日付を使っているアプリで見る

日付の扱いが主役のアプリです(コードは各記事に全文あり)。

アプリ日付の使われ方
年齢計算アプリ誕生日と今日の差分。2月29日生まれの扱いが論点
誕生日カウントダウンfromisoformat で読み戻して残り日数を数える
カウントダウンタイマーstrptime で目標時刻を解析し残り時間を更新
デジタル時計strftime で1秒ごとに整形して表示する最小例
カレンダー表示アプリcalendar で月間カレンダーを組み立てる
習慣トラッカー過去7日の日付を timedelta で作る
通知スケジューラ指定時刻と比較して通知。繰り返し間隔も日付計算
プロジェクト管理ツール開始日と終了日からガントチャートのバー長を計算
バックアップツールstrftime で世代管理用のタイムスタンプを作る
時間追跡アプリ開始・終了から作業時間を日次で合計

配当カレンダー生成ツールcalendar を継承して月間カレンダーを描き、株価データの定期取得は毎回「直近5営業日」を取り直して重複を潰します。一覧は初心者向け中級者向けへ。

10. よくある質問(FAQ)

Q. pytz と zoneinfo はどちらを使えばいいですか?

新しく書くコードは zoneinfo です。3.9 から標準ライブラリに入っており(Windows は tzdata が要ります)、datetime と自然に組み合わさります。pytz は localize() を忘れると日本時間が19分ずれます。既存コードの書き換えは急ぎません。

Q. datetime.utcnow() を使っているコードはどう直せばいいですか?

datetime.now(timezone.utc) に置き換えます。戻り値が naive から aware に変わるため、naive な値と引き算すると TypeError です。相手も aware に揃えるか、.replace(tzinfo=None) で落としてください。

Q. 「1か月後」を1行で書く方法はありますか?

標準ライブラリだけではありません。6章add_months を持つか python-dateutil を導入します。どちらにしても「1月31日の1か月後をいつにするか」は決める必要があります。

Q. 日付を保存するとき、どの形式が無難ですか?

ISO 8601(2026-09-20T07:05:03)です。isoformat() で書いて fromisoformat() で読めば書式指定が要らず、文字列のまま並べ替えても日付順になります。

Q. 曜日を日本語で表示したいのですが、ロケールを変えるべきですか?

"月火水木金土日"[d.weekday()] と自分で当てるほうが安定します。locale.setlocale() は指定できる名前がOSで異なり、環境を移した途端に動かなくなることがあります。

本記事は、生成AIを活用して下書きし、運営者が内容を確認・編集したうえで公開しています。AIの利用方針は免責事項をご覧ください。

11. まとめと次の一歩

要点は4つです。

  • 日付だけなら date、時刻も要るなら datetime、期間は timedelta
  • 変換は f = format(出力)、p = parse(入力)。ISO形式なら書式指定が要らない
  • 月単位の加算は標準にない。末日の丸め方は自分で決める
  • タイムゾーンは zoneinfoWindows では tzdata が別途必要。naive と aware は混ぜない

表を眺めるより手を動かすほうが定着します。デジタル時計で書式を差し替えるところから。標準ライブラリの全体像はPythonライブラリ一覧、エラーで止まったらPythonエラー辞典、次に作るものに迷ったらPythonで作れるもの一覧が入口です。

土台から固めたい方は書籍を1冊通すのも手です。このページを毎回開かずに書けるようになりたい方向け。候補はPython入門書のおすすめ2冊にまとめています(書籍紹介ページにはアフィリエイト広告を含みます)。

📌
参考にした一次情報と検証環境(2026-09-20 確認)

仕様は公式ドキュメント日本語版の datetimezoneinfocalendar を参照。掲載コードと出力は Python 3.12.10(Windows 11)で1ファイルにまとめて実行し、記事側と一致することを機械照合しています。版による違いは 3.14.7 でも確認しました。