💡 この記事でわかること
datetimeモジュールのdate・datetime・timedeltaの役割- 現在の日時の取得と、年・月・日・曜日の取り出し方
strftime(日時→文字列)とstrptime(文字列→日時)の書式指定timedeltaを使った「〇日後」「日数の差」の計算方法- タイムゾーンの有無による違いと、よくあるエラー
1. 日付・時刻を扱うには?
Pythonで日付や時刻を扱うには、
👉 標準ライブラリの datetime モジュールを使います。
💡 日付を「2026-09-20」のような文字列のままにしておくと、「7日後はいつか」「2つの日付は何日離れているか」といった計算ができません。日付や時刻専用の型に変換しておくと、計算や比較を簡単に書けるようになります。
datetime モジュールには、主に次の3つの型があります。
| 型 | 表すもの | 例 |
|---|---|---|
date | 日付だけ(年・月・日) | 2026年9月20日 |
datetime | 日付と時刻(年・月・日・時・分・秒) | 2026年9月20日 10:30:45 |
timedelta | 時間の長さ(〇日・〇時間など) | 7日間、3時間 |
使う前に、ファイルの先頭で次のように読み込みます。
from datetime import datetime, date, timedelta👉 import datetime とだけ書いた場合は、モジュール名とクラス名がどちらも datetime なので、datetime.datetime.now() のように書く必要があります。この記事では、短く書ける from datetime import ... の形で進めます。
👉 Pythonのモジュール(importの使い方)についての記事はこちら
2. 現在の日時を取得する
datetime.now() で現在の日時、date.today() で今日の日付を取得できます。
from datetime import datetime, date
now = datetime.now()
print(now) # 例:2026-09-20 10:30:45.123456(実行した瞬間の日時)
today = date.today()
print(today) # 例:2026-09-20(今日の日付)特定の日時を自分で作りたいときは、datetime(年, 月, 日, 時, 分, 秒) と書きます。作った日時からは、年・月・日などを取り出せます。
from datetime import datetime
dt = datetime(2026, 9, 20, 10, 30, 45)
print(dt) # 2026-09-20 10:30:45
print(dt.year) # 2026
print(dt.month) # 9
print(dt.day) # 20
print(dt.hour) # 10
print(dt.minute) # 30
print(dt.second) # 45
print(dt.weekday()) # 6(曜日:月曜=0、火曜=1 … 日曜=6)👉 weekday() は月曜を0として数えます。この日(2026年9月20日)は日曜日なので、6が返ってきます。月曜を1として数える isoweekday() もあります(日曜は7)。
曜日を日本語で表示したいときは、リストと組み合わせると簡単です。
youbi = ["月", "火", "水", "木", "金", "土", "日"]
print(youbi[dt.weekday()]) # 日3. 日時を文字列にする(strftime)
日時を好きな形式の文字列にしたいときは strftime() を使います。「%Y」「%m」のような書式コードで、出力の形を指定します。
dt = datetime(2026, 9, 20, 10, 30, 45)
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2026-09-20 10:30:45
print(dt.strftime("%Y/%m/%d")) # 2026/09/20
print(dt.strftime("%Y年%m月%d日 %H時%M分")) # 2026年09月20日 10時30分| 書式コード | 意味 | 例 |
|---|---|---|
%Y | 年(4桁) | 2026 |
%m | 月(2桁) | 09 |
%d | 日(2桁) | 20 |
%H | 時(24時間表記) | 10 |
%M | 分 | 30 |
%S | 秒 | 45 |
%y | 年(下2桁) | 26 |
%A | 曜日(英語名) | Sunday |
👉 月は小文字の %m、分は大文字の %M です。取り違えやすいので注意してください。また、%A の曜日名は、環境の設定によって表示が変わることがあります。日本語で表示したいときは、先ほどのようにリストを使うほうが確実です。
f-stringの中でも、: のあとに同じ書式コードを書けます。
print(f"{dt:%Y-%m-%d}") # 2026-09-20
print(f"{dt:%H:%M}") # 10:30👉 Pythonの文字列操作(f-stringの書式指定)についての記事はこちら
日時をJSONやファイルに保存するときは、文字列にしてから書き込みます。isoformat() を使うと、標準的な形式の文字列にできます。
print(dt.isoformat()) # 2026-09-20T10:30:45👉 PythonのJSON(日時を保存するときの注意点)についての記事はこちら
4. 文字列を日時にする(strptime)
逆に、「2026-09-20 10:30」のような文字列を日時の型に変換するのが strptime() です。第2引数に、その文字列の書式を指定します。
from datetime import datetime
text = "2026-09-20 10:30"
dt = datetime.strptime(text, "%Y-%m-%d %H:%M")
print(dt) # 2026-09-20 10:30:00
print(type(dt)) # <class 'datetime.datetime'>👉 strftime は「format(整形)」で日時→文字列、strptime は「parse(解析)」で文字列→日時、と覚えると混同しにくくなります。
指定した書式と文字列の形がずれていると、エラーになります。
datetime.strptime("2026-09-20", "%Y/%m/%d")
# ValueError: time data '2026-09-20' does not match format '%Y/%m/%d'
# (文字列はハイフン区切りなのに、書式がスラッシュ区切りになっている)👉 ユーザーの入力など、形式が保証できない文字列を変換するときは、try-except で ValueError を受け止めるのが基本です。
「2026-09-20T10:30:00」のような標準形式(ISO形式)の文字列なら、書式の指定が不要な fromisoformat() が便利です。
from datetime import datetime, date
print(datetime.fromisoformat("2026-09-20T10:30:00")) # 2026-09-20 10:30:00
print(date.fromisoformat("2026-09-20")) # 2026-09-205. 日付の計算をする(timedelta)
timedelta は「時間の長さ」を表す型で、日時に足したり引いたりすると、「〇日後」「〇時間前」を計算できます。
from datetime import datetime, timedelta
dt = datetime(2026, 9, 20, 10, 30, 45)
print(dt + timedelta(days=7)) # 2026-09-27 10:30:45(7日後)
print(dt - timedelta(hours=3)) # 2026-09-20 07:30:45(3時間前)
print(dt + timedelta(days=1, hours=2, minutes=30)) # 2026-09-21 13:00:45👉 timedelta には days・hours・minutes・seconds・weeks を指定できます。「〇か月」「〇年」は指定できない点に注意してください(指定するとエラーになります)。月の長さは28〜31日と一定ではないためです。
print(datetime(2026, 1, 31) + timedelta(days=30)) # 2026-03-02(「1か月後」にはならない)月単位の計算を正確に行いたい場合は、外部ライブラリ(python-dateutil の relativedelta など)を使うのが一般的です。
6. 日時の差を求める・比較する
日時どうしを引き算すると、その差が timedelta として返ってきます。比較演算子( < や == )で、どちらが前か後かも判定できます。
a = datetime(2026, 9, 20, 10, 0)
b = datetime(2026, 9, 22, 15, 30)
diff = b - a
print(diff) # 2 days, 5:30:00
print(diff.days) # 2(日数の部分)
print(diff.total_seconds()) # 192600.0(全体の秒数)
print(diff.total_seconds() / 3600) # 53.5(全体の時間数)
print(a < b) # True(aのほうが前)
print(a == b) # False💡 diff.seconds は、全体の秒数ではなく「日数を除いた残りの秒数」です。この例では19800(5時間30分)が返り、2日分は含まれません。全体の秒数が欲しいときは total_seconds() を使ってください。
7. 実践例:締め切りまでの日数を求める
学んだことを組み合わせて、「締め切りまであと何日か」を求める例です。日付だけを扱うので date を使います。
from datetime import date
today = date(2026, 9, 20) # 実際に使うときは date.today() にする
deadline = date(2026, 12, 31)
remaining = (deadline - today).days
print(f"締め切りまであと{remaining}日") # 締め切りまであと102日👉 日付の引き算の結果は timedelta なので、.days で日数だけを取り出しています。ここでは結果を固定するため日付を直接書いていますが、実際のプログラムでは date.today() に置き換えて使います。
8. タイムゾーンの注意点
datetime.now() が返す日時には、タイムゾーンの情報がありません。パソコンの設定の時刻がそのまま入るので、国内でパソコン上だけで動かす分には問題になりにくいのですが、サーバーなどで動かすと、設定によっては日本時間とずれることがあります。日本時間だと明示したいときは、ZoneInfo を使います。
from datetime import datetime
from zoneinfo import ZoneInfo
now = datetime.now(ZoneInfo("Asia/Tokyo"))
print(now.tzinfo) # Asia/Tokyo
print(now.utcoffset()) # 9:00:00(UTCとの差)👉 zoneinfo はPython 3.9以降の標準ライブラリです。Windowsなど、環境によってはタイムゾーンのデータが入っておらず、pip install tzdata が必要になることがあります。
タイムゾーンありの日時と、なしの日時は、そのままでは比較できません。
naive = datetime.now() # タイムゾーンなし
aware = datetime.now(ZoneInfo("Asia/Tokyo")) # タイムゾーンあり
naive < aware
# TypeError: can't compare offset-naive and offset-aware datetimesエラーになったら、どちらかに揃えます。別のタイムゾーンの時刻に変換したいときは astimezone() を使います。
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_dt = datetime(2026, 9, 20, 1, 0, tzinfo=timezone.utc)
print(utc_dt) # 2026-09-20 01:00:00+00:00
print(utc_dt.astimezone(ZoneInfo("Asia/Tokyo"))) # 2026-09-20 10:00:00+09:009. datetime 早見表
| 書き方 | できること |
|---|---|
datetime.now() / date.today() | 現在の日時 / 今日の日付を取得する |
datetime(2026, 9, 20, 10, 30) | 特定の日時を作る |
dt.year / dt.month / dt.day | 年・月・日を取り出す(時・分・秒も同様) |
dt.weekday() | 曜日を数字で取得する(月曜=0〜日曜=6) |
dt.strftime("%Y-%m-%d") | 日時を、指定した形式の文字列にする |
datetime.strptime(text, 書式) | 文字列を日時に変換する |
datetime.fromisoformat(text) | ISO形式の文字列を日時に変換する |
dt + timedelta(days=7) | 〇日後・〇時間前を計算する |
b - a / .days / .total_seconds() | 日時の差を求める / 日数 / 全体の秒数 |
datetime.now(ZoneInfo("Asia/Tokyo")) | タイムゾーン付きの現在日時を取得する |
10. まとめ
- 日付・時刻は標準ライブラリの
datetimeで扱い、date・datetime・timedeltaの3つの型を使い分ける - 日時→文字列は
strftime()、文字列→日時はstrptime()(月は%m、分は%M) - 「〇日後」の計算は
timedelta、日時の引き算の結果もtimedelta(全体の秒数はtotal_seconds()) timedeltaに月・年は指定できない(月単位の計算は外部ライブラリを使う)datetime.now()はタイムゾーンなし。あり・なしの日時は、そのままでは比較できない
👉 書式コードを全部暗記する必要はありません。「日時を文字列にしたい」「〇日後を求めたい」といったやりたいことから、早見表で引けるようにしておけば十分です。