Pythonで日付や時刻を扱う場面は、ログの記録や予約日時の管理、レポート作成など、実務でも学習でも非常によく登場します。
本記事では、Python標準ライブラリであるdatetimeモジュールを使って、現在時刻の取得から日付計算、タイムゾーン対応までを、サンプルコード付きで丁寧に解説します。
初学者の方でも、この記事を通して実務レベルで使える基礎をしっかり身につけられる構成になっています。
Pythonのdatetimeとは
datetimeモジュールでできること

Pythonのdatetimeモジュールは、日付や時刻を扱うための標準ライブラリです。
このモジュールを使うことで、日付や時刻に関するさまざまな操作を簡単に行うことができます。
例えば次のようなことが可能です。
- 現在の日時を取得する
- 特定の日付や時刻を表すオブジェクトを作成する
- 日付や時刻に対して加算・減算を行う
- 日付や時刻を文字列に変換したり、その逆を行う
- タイムゾーン(UTCや日本時間など)を考慮した日時を扱う
実務で日時を扱う処理のほとんどは、このdatetimeモジュールで対応できます。
まずは全体像を押さえたうえで、具体的なクラスを見ていきます。
datetimeの基本クラス

datetimeモジュールには、いくつかの基本クラスが定義されています。
それぞれの役割を理解しておくと、後の操作がぐっとわかりやすくなります。
代表的なクラスは次の4つです。
| クラス名 | 役割 | 主なフィールド例 |
|---|---|---|
| date | 日付(年・月・日)だけを表す | year, month, day |
| time | 時刻(時・分・秒など)だけを表す | hour, minute, second, microsecond |
| datetime | 日付と時刻をまとめて表す | year, month, day, hour, minute など |
| timedelta | 時間の差(期間・長さ)を表す | days, seconds, microseconds |
もっともよく使うのはdatetimeクラスとtimedeltaクラスです。
日付と時刻を一緒に扱えるdatetimeを中心に、期間を表すtimedeltaで加算・減算していくイメージを持っておくと理解しやすくなります。
基本的なインポートは次のように行います。
from datetime import date, time, datetime, timedelta
# それぞれのクラスを使ってオブジェクトを作成する例
# 日付だけ
d = date(2025, 1, 1) # 2025年1月1日
# 時刻だけ
t = time(14, 30, 0) # 14時30分0秒
# 日付と時刻
dt = datetime(2025, 1, 1, 14, 30, 0) # 2025年1月1日14:30:00
# 期間(差分) 1日と2時間
delta = timedelta(days=1, hours=2)
現在日時を取得する方法
datetime.now()で現在日時を取得

現在の日時はdatetime.now()を使うことで取得できます。
もっとも基本的でよく使うメソッドです。
from datetime import datetime
# 現在のローカル日時を取得
now = datetime.now()
print("現在の日時:", now)
print("型:", type(now))
現在の日時: 2025-12-20 15:42:31.123456
型: <class 'datetime.datetime'>
このように、datetime.now()は実行した瞬間のローカル(システムのタイムゾーン)の日時を表すdatetimeオブジェクトを返します。
ミリ秒より細かいマイクロ秒(microsecond)まで含まれている点も特徴です。
datetime.today()との違い
datetime.today()も現在日時を返すメソッドとしてよく見かけます。
初学者の方はnow()との違いが気になると思いますが、実用上はほとんど同じ挙動です。
from datetime import datetime
now = datetime.now()
today = datetime.today()
print("now(): ", now)
print("today(): ", today)
print("等しいか?", now == today)
now(): 2025-12-20 15:42:31.123456
today(): 2025-12-20 15:42:31.123456
等しいか? True
現在のPython(標準的な環境)では、today()は内部的にnow()を呼び出しているだけなので、戻り値も型も同じです。
歴史的な経緯で両方が存在していますが、新しく書くコードではdatetime.now()を使うとよいでしょう。
timezone(タイムゾーン)付きの現在時刻

タイムゾーンを明示的に含んだ現在時刻を取得したい場合は、datetime.now(timezone.utc)のようにtimezoneオブジェクトを渡します。
from datetime import datetime, timezone
# UTC(協定世界時)の現在日時を取得
now_utc = datetime.now(timezone.utc)
print("UTC現在日時:", now_utc)
print("tzinfo:", now_utc.tzinfo)
UTC現在日時: 2025-12-20 06:42:31.123456+00:00
tzinfo: UTC
このように、tzinfoが設定されているdatetimeを「タイムゾーン付き(aware)なdatetime」と呼びます。
一方、datetime.now()だけで取得した日時はタイムゾーン情報を持たないnaive(ナイーブ)なdatetimeです。
タイムゾーンを本格的に扱う場合はzoneinfoモジュールを使いますが、それについては後の「タイムゾーンと注意点」で解説します。
日付・時刻の基本操作
日付文字列をdatetimeに変換

現実のアプリケーションでは、日時は「文字列」として保存されていることが多いです。
そこで重要になるのが、datetime.strptime()を使った文字列からdatetimeへの変換です。
from datetime import datetime
# 文字列としての日付・時刻
date_str = "2025-12-20 14:30:00"
# フォーマットを指定して解析する
dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print("変換結果:", dt)
print("型:", type(dt))
変換結果: 2025-12-20 14:30:00
型: <class 'datetime.datetime'>
strptime()では、解析したい文字列の形と一致する書式(フォーマット文字列)を指定する必要があります。
代表的な書式指定子は次のようなものがあります。
| 指定子 | 意味 | 例 |
|---|---|---|
| %Y | 西暦4桁 | 2025 |
| %m | 月(ゼロ埋め) | 01〜12 |
| %d | 日(ゼロ埋め) | 01〜31 |
| %H | 時(24時間制) | 00〜23 |
| %M | 分 | 00〜59 |
| %S | 秒 | 00〜59 |
例えば"2025/12/20"という文字列であれば"%Y/%m/%d"という書式を指定するなど、文字列の形に合わせてフォーマットを変える必要があります。
datetimeを文字列に変換

次は逆に、datetimeオブジェクトを人が読みやすい文字列に変換する方法です。
こちらにはdatetime.strftime()を使います。
from datetime import datetime
dt = datetime(2025, 12, 20, 14, 30, 0)
# 年月日のみ
date_str = dt.strftime("%Y-%m-%d")
# 年月日時分秒
datetime_str = dt.strftime("%Y-%m-%d %H:%M:%S")
print("日付文字列:", date_str)
print("日時文字列:", datetime_str)
日付文字列: 2025-12-20
日時文字列: 2025-12-20 14:30:00
strptime()とstrftime()はペアで覚えるとよいです。
同じフォーマット指定子を使うため、「この文字列をパースしたいなら、このフォーマット」「この形式で表示したいなら、このフォーマット」という対応関係が自然と身についていきます。
年月日・時分秒の取り出しと更新

datetimeオブジェクトから、年や月、日、時刻などの各要素を取り出すには、属性にアクセスします。
from datetime import datetime
dt = datetime(2025, 12, 20, 14, 30, 45)
print("年:", dt.year)
print("月:", dt.month)
print("日:", dt.day)
print("時:", dt.hour)
print("分:", dt.minute)
print("秒:", dt.second)
年: 2025
月: 12
日: 20
時: 14
分: 30
秒: 45
datetimeオブジェクトはイミュータブル(不変)なので、直接属性を書き換えることはできません。
その代わり、replace()メソッドで一部の値だけを変えた新しいdatetimeを作ります。
from datetime import datetime
dt = datetime(2025, 12, 20, 14, 30, 45)
print("元の日時:", dt)
# 年だけ変更
dt_2026 = dt.replace(year=2026)
# 月と日を変更
dt_jan = dt.replace(month=1, day=1)
print("年だけ変更:", dt_2026)
print("月日を変更:", dt_jan)
元の日時: 2025-12-20 14:30:45
年だけ変更: 2026-12-20 14:30:45
月日を変更: 2025-01-01 14:30:45
replace()は一部だけ差し替えるときに非常に便利です。
特定の日付の「時刻だけを00:00:00にそろえる」といった用途でもよく使われます。
日付の加算・減算

日付や時刻同士の計算には、timedeltaクラスを使います。
timedeltaは「何日・何時間・何分」といった期間を表すクラスで、datetimeとの加算・減算が可能です。
from datetime import datetime, timedelta
dt = datetime(2025, 12, 20, 14, 30, 0)
# 7日後
one_week_later = dt + timedelta(days=7)
# 1日前
yesterday = dt - timedelta(days=1)
# 2時間30分後
after_2h30m = dt + timedelta(hours=2, minutes=30)
print("元の日時:", dt)
print("1週間後:", one_week_later)
print("1日前:", yesterday)
print("2時間30分後:", after_2h30m)
元の日時: 2025-12-20 14:30:00
1週間後: 2025-12-27 14:30:00
1日前: 2025-12-19 14:30:00
2時間30分後: 2025-12-20 17:00:00
このように、datetime ± timedelta → datetimeという形で日付や時刻の加算・減算ができます。
月単位の加算(1か月後など)は単純ではないため、標準ライブラリだけでは直接は扱いにくいですが、日単位や時間単位の計算であればtimedeltaで十分対応できます。
日付の比較

datetimeオブジェクトは、比較演算子(>, <, >=, <=, ==, !=)を使って直接比較することができます。
from datetime import datetime
dt1 = datetime(2025, 12, 20, 10, 0, 0)
dt2 = datetime(2025, 12, 20, 15, 0, 0)
dt3 = datetime(2025, 12, 21, 9, 0, 0)
print("dt1 < dt2:", dt1 < dt2) # 10時は15時より前
print("dt2 < dt3:", dt2 < dt3) # 20日の15時は21日の9時より前
print("dt1 == dt2:", dt1 == dt2)
dt1 < dt2: True
dt2 < dt3: True
dt1 == dt2: False
比較のルールは「暦として早い方が小さい」という直感的なものです。
ただし、タイムゾーン付きのdatetimeとタイムゾーンなしのdatetimeを混在させて比較しようとするとエラーになります。
この点については、次の「タイムゾーンと注意点」で詳しく説明します。
タイムゾーンと注意点
timezone(タイムゾーン)対応のdatetime

datetimeには、タイムゾーンを持たないnaive(ナイーブ)なものと、タイムゾーン情報を持つaware(アウェア)なものの2種類があります。
- naive:
tzinfoがNone。タイムゾーン不明の日時。 - aware:
tzinfoにタイムゾーンオブジェクトが設定されている。
タイムゾーン付きdatetimeを扱うには、Python3.9以降で利用できるzoneinfoモジュールが便利です。
from datetime import datetime
from zoneinfo import ZoneInfo # Python 3.9以降
# 日本時間(JST)の現在日時
now_jst = datetime.now(ZoneInfo("Asia/Tokyo"))
# アメリカ・ニューヨーク時間
now_ny = datetime.now(ZoneInfo("America/New_York"))
print("日本時間:", now_jst)
print("ニューヨーク時間:", now_ny)
print("日本時間 tzinfo:", now_jst.tzinfo)
日本時間: 2025-12-20 15:42:31.123456+09:00
ニューヨーク時間: 2025-12-20 01:42:31.123456-05:00
日本時間 tzinfo: Asia/Tokyo
実務では、必ず「naiveで扱うのか」「タイムゾーン付きで扱うのか」をプロジェクト内で統一することが重要です。
特にサーバーサイド開発では、後述するようにUTCで統一して保存し、表示時にローカル時間に変換する運用が一般的です。
UTCとローカル時間の変換

世界共通の基準となる時間がUTC(協定世界時)です。
サーバーやDBではUTCで保存・処理し、ユーザーに表示するときだけ各地域のローカル時間に変換する設計が推奨されます。
UTCとローカル時間(ここでは日本時間)との変換は、astimezone()メソッドで行います。
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
# UTCの現在日時を取得
now_utc = datetime.now(timezone.utc)
# 日本時間に変換
now_jst = now_utc.astimezone(ZoneInfo("Asia/Tokyo"))
# ニューヨーク時間に変換
now_ny = now_utc.astimezone(ZoneInfo("America/New_York"))
print("UTC:", now_utc)
print("日本時間:", now_jst)
print("ニューヨーク時間:", now_ny)
UTC: 2025-12-20 06:42:31.123456+00:00
日本時間: 2025-12-20 15:42:31.123456+09:00
ニューヨーク時間: 2025-12-20 01:42:31.123456-05:00
ここで重要なのは、タイムゾーン付きdatetime同士なら、異なるタイムゾーンであっても正しく比較・計算できるという点です。
Python内部ではすべてUTCに変換してから処理するため、世界中のユーザーが利用するサービスでも整合性を保てます。
サマータイム(DST)とdatetimeの落とし穴

タイムゾーンを扱う際に最もやっかいなのがサマータイム(DST: Daylight Saving Time)です。
日本にはサマータイムがありませんが、ヨーロッパやアメリカなど多くの地域では、夏の一定期間だけ時計を1時間進めます。
その結果、次のような問題が発生します。
- 存在しない時間が生まれる(時計を1時間進める瞬間)
- 同じ時刻が2回現れる(時計を1時間戻す瞬間)
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
# アメリカ・ニューヨークのサマータイム終了付近の例(仮の日付)
dt_before = datetime(2025, 11, 2, 0, 30, tzinfo=ZoneInfo("America/New_York"))
dt_after = dt_before + timedelta(hours=2)
print("開始時刻:", dt_before)
print("2時間後:", dt_after)
print("経過時間(実際):", (dt_after - dt_before).total_seconds() / 3600, "時間")
開始時刻: 2025-11-02 00:30:00-04:00
2時間後: 2025-11-02 01:30:00-05:00
経過時間(実際): 2.0 時間
上記はあくまで例ですが、サマータイムの切り替えによって、見かけ上の時計の時刻と実際に経過した時間が直感とずれるケースがあります。
このような問題を避けるために、実務では次のような指針がよく採用されます。
- アプリ内部やデータベースではUTCで一元管理する
- ユーザーへの表示・入力のときだけローカルタイムゾーンに変換する
- サマータイム区域での複雑な業務ロジックがある場合は、ライブラリの挙動を事前に検証して設計する
ローカル時間だけに依存した計算は、サマータイム区域ではバグの温床になりやすいため、可能な限りUTCでの処理を心がけてください。
まとめ
Pythonのdatetimeモジュールを使うことで、日付や時刻の取得・変換・計算・比較といった基本操作から、タイムゾーンを考慮した高度な処理まで、一通りのことが標準ライブラリだけで実現できます。
datetimeとtimedeltaを軸に、strptime/strftimeで文字列と相互変換し、タイムゾーンはUTC基準で扱うという流れを押さえておけば、多くの場面に対応できます。
まずはサンプルコードを実際に動かしながら、自分のアプリケーションで必要な操作を少しずつ取り入れていくことをおすすめします。
