「Pythonで今の日付や時刻を取得したい」
「ログファイルに記録する時刻を整形したい」
「2つの日付の差を計算したい」
「文字列で書かれた日付をプログラムで処理したい」
そんなときに使うのが、Pythonのdatetime
モジュールです。
datetimeモジュールは、日付や時刻を扱うためのPython標準ライブラリです。
Webアプリケーション、データ分析、ログ管理など、あらゆる場面で必要になる重要なツールです。
この記事でわかること
- datetimeモジュールの基本的な使い方
- 現在の日付・時刻の取得方法
- 日付のフォーマット変換(見やすい形に変更)
- 文字列から日付への変換
- 日付の計算(何日後、何時間前など)
- 実際のプログラムでの活用例
datetimeモジュールとは?

datetimeが必要な理由
普通の文字列では困ること:
# 文字列だと計算ができない
date1 = "2024-01-15"
date2 = "2024-01-20"
# date2 - date1 = ?(計算できない)
datetimeオブジェクトなら:
from datetime import datetime
date1 = datetime(2024, 1, 15)
date2 = datetime(2024, 1, 20)
diff = date2 - date1
print(diff.days) # 5(5日の差)
1-2. よく使うクラス
クラス | 用途 | 例 |
---|---|---|
datetime | 日付と時刻 | 2024-01-15 14:30:45 |
date | 日付のみ | 2024-01-15 |
time | 時刻のみ | 14:30:45 |
timedelta | 時間の差 | 5日間、3時間 |
現在の日付・時刻を取得しよう
基本的な取得方法
from datetime import datetime
# 現在の日時を取得
now = datetime.now()
print(now)
# 結果例:2024-06-02 14:35:27.123456
print(type(now))
# 結果:<class 'datetime.datetime'>
日付のみ、時刻のみを取得
from datetime import datetime, date, time
# 現在の日付のみ
today = date.today()
print(today) # 2024-06-02
# 現在の時刻のみ
current_time = datetime.now().time()
print(current_time) # 14:35:27.123456
特定の日時を作成
# 特定の日時を指定
specific_datetime = datetime(2024, 12, 25, 10, 30, 0)
print(specific_datetime) # 2024-12-25 10:30:00
# 日付のみ指定(時刻は00:00:00)
specific_date = datetime(2024, 12, 25)
print(specific_date) # 2024-12-25 00:00:00
日時の情報を取り出そう
年月日・時分秒の取得
from datetime import datetime
now = datetime.now()
print(f"現在時刻: {now}")
# 年月日を取得
print(f"年: {now.year}") # 例:2024
print(f"月: {now.month}") # 例:6
print(f"日: {now.day}") # 例:2
# 時分秒を取得
print(f"時: {now.hour}") # 例:14
print(f"分: {now.minute}") # 例:35
print(f"秒: {now.second}") # 例:27
print(f"マイクロ秒: {now.microsecond}") # 例:123456
曜日の取得
# 曜日を数字で取得(月曜日=0, 日曜日=6)
print(f"曜日(数字): {now.weekday()}") # 例:6(日曜日)
# 曜日を日本語で表示
weekdays = ["月", "火", "水", "木", "金", "土", "日"]
print(f"曜日: {weekdays[now.weekday()]}曜日") # 例:日曜日
その他の便利な情報
# ISO形式で出力
print(f"ISO形式: {now.isoformat()}")
# 例:2024-06-02T14:35:27.123456
# タイムスタンプ(1970年1月1日からの秒数)
print(f"タイムスタンプ: {now.timestamp()}")
# 例:1717310127.123456
日時をいろんな形式で表示しよう(strftime)

strftimeの基本
strftime
を使うと、日時を好きな形式の文字列に変換できます。
from datetime import datetime
now = datetime.now()
# 基本的な形式
print(now.strftime("%Y-%m-%d")) # 2024-06-02
print(now.strftime("%Y/%m/%d")) # 2024/06/02
print(now.strftime("%H:%M:%S")) # 14:35:27
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 2024-06-02 14:35:27
よく使うフォーマット一覧
記号 | 意味 | 例 |
---|---|---|
%Y | 年(4桁) | 2024 |
%y | 年(2桁) | 24 |
%m | 月(01-12) | 06 |
%B | 月名(英語) | June |
%d | 日(01-31) | 02 |
%H | 時(00-23) | 14 |
%I | 時(01-12) | 02 |
%M | 分(00-59) | 35 |
%S | 秒(00-59) | 27 |
%A | 曜日名(英語) | Sunday |
%a | 曜日名(英語短縮) | Sun |
実用的なフォーマット例
from datetime import datetime
now = datetime.now()
# 日本でよく使われる形式
print(now.strftime("%Y年%m月%d日")) # 2024年06月02日
print(now.strftime("%m/%d/%Y")) # 06/02/2024
print(now.strftime("%Y-%m-%d (%A)")) # 2024-06-02 (Sunday)
# ログファイル用
print(now.strftime("[%Y-%m-%d %H:%M:%S]")) # [2024-06-02 14:35:27]
# ファイル名用(特殊文字を避ける)
print(now.strftime("%Y%m%d_%H%M%S")) # 20240602_143527
# 12時間表記
print(now.strftime("%Y/%m/%d %I:%M:%S %p")) # 2024/06/02 02:35:27 PM
実際の使用例
from datetime import datetime
def create_log_entry(message):
"""ログエントリを作成する関数"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return f"[{timestamp}] {message}"
def generate_filename():
"""日付を含むファイル名を生成"""
date_str = datetime.now().strftime("%Y%m%d")
return f"report_{date_str}.txt"
# 使用例
print(create_log_entry("プログラム開始"))
# [2024-06-02 14:35:27] プログラム開始
print(generate_filename())
# report_20240602.txt
文字列を日時に変換しよう(strptime)
基本的な変換
from datetime import datetime
# 文字列をdatetimeオブジェクトに変換
date_str = "2024-06-15 10:30:00"
dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(dt) # 2024-06-15 10:30:00
print(type(dt)) # <class 'datetime.datetime'>
いろんな形式の文字列を変換
# さまざまな形式の日付文字列
examples = [
("2024/06/15", "%Y/%m/%d"),
("15-Jun-2024", "%d-%b-%Y"),
("June 15, 2024", "%B %d, %Y"),
("2024-06-15T10:30:00", "%Y-%m-%dT%H:%M:%S"),
("20240615", "%Y%m%d")
]
for date_string, format_string in examples:
dt = datetime.strptime(date_string, format_string)
print(f"{date_string} → {dt}")
エラー処理
from datetime import datetime
def safe_parse_date(date_string, format_string):
"""安全に日付を変換する関数"""
try:
return datetime.strptime(date_string, format_string)
except ValueError as e:
print(f"日付の変換に失敗しました: {e}")
return None
# 使用例
result = safe_parse_date("2024-13-45", "%Y-%m-%d") # 無効な日付
if result:
print(f"変換成功: {result}")
else:
print("変換に失敗しました")
日付の計算をしよう(timedelta)

timedeltaの基本
from datetime import datetime, timedelta
now = datetime.now()
print(f"現在: {now}")
# 未来の日時を計算
tomorrow = now + timedelta(days=1)
next_week = now + timedelta(weeks=1)
next_month = now + timedelta(days=30) # 約1ヶ月
print(f"明日: {tomorrow}")
print(f"来週: {next_week}")
print(f"来月: {next_month}")
過去の日時を計算
# 過去の日時を計算
yesterday = now - timedelta(days=1)
last_week = now - timedelta(weeks=1)
three_hours_ago = now - timedelta(hours=3)
print(f"昨日: {yesterday}")
print(f"先週: {last_week}")
print(f"3時間前: {three_hours_ago}")
timedeltaで指定できる単位
from datetime import timedelta
# さまざまな時間単位
td = timedelta(
days=7, # 日
hours=3, # 時間
minutes=30, # 分
seconds=45, # 秒
microseconds=123, # マイクロ秒
weeks=2 # 週
)
print(f"合計: {td}")
# 結果:21 days, 3:30:45.000123
日付の差を計算
from datetime import datetime
# 2つの日付の差を計算
start_date = datetime(2024, 1, 1)
end_date = datetime(2024, 6, 15)
diff = end_date - start_date
print(f"差: {diff}") # 166 days, 0:00:00
print(f"日数: {diff.days}") # 166
print(f"秒数: {diff.seconds}") # 0
print(f"総秒数: {diff.total_seconds()}") # 14342400.0
実用的な計算例
from datetime import datetime, timedelta
def calculate_age(birth_date):
"""年齢を計算する関数"""
today = datetime.now()
age = today - birth_date
return age.days // 365 # 概算の年齢
def next_business_day(date_obj):
"""次の営業日を計算(土日を除く)"""
next_day = date_obj + timedelta(days=1)
while next_day.weekday() >= 5: # 土曜日=5, 日曜日=6
next_day += timedelta(days=1)
return next_day
def days_until_deadline(deadline_str):
"""締切までの日数を計算"""
deadline = datetime.strptime(deadline_str, "%Y-%m-%d")
today = datetime.now()
diff = deadline - today
return diff.days
# 使用例
birth = datetime(1990, 5, 15)
print(f"年齢: {calculate_age(birth)}歳")
today = datetime.now()
next_biz = next_business_day(today)
print(f"次の営業日: {next_biz.strftime('%Y-%m-%d (%A)')}")
days_left = days_until_deadline("2024-12-31")
print(f"年末まで: {days_left}日")
実際のプログラムでの活用例

ログファイルの管理
from datetime import datetime
import os
class Logger:
def __init__(self, log_dir="logs"):
self.log_dir = log_dir
# ログディレクトリが存在しない場合は作成
if not os.path.exists(log_dir):
os.makedirs(log_dir)
def log(self, message, level="INFO"):
"""ログメッセージを記録"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {level}: {message}"
# 日付ごとのログファイル
date_str = datetime.now().strftime("%Y%m%d")
log_file = os.path.join(self.log_dir, f"app_{date_str}.log")
with open(log_file, "a", encoding="utf-8") as f:
f.write(log_entry + "\n")
print(log_entry)
# 使用例
logger = Logger()
logger.log("アプリケーション開始")
logger.log("ユーザーログイン", "INFO")
logger.log("エラーが発生しました", "ERROR")
営業時間の判定
from datetime import datetime, time
class BusinessHours:
def __init__(self, open_time="09:00", close_time="18:00"):
self.open_time = datetime.strptime(open_time, "%H:%M").time()
self.close_time = datetime.strptime(close_time, "%H:%M").time()
def is_open(self, check_time=None):
"""営業時間内かどうかを判定"""
if check_time is None:
check_time = datetime.now().time()
# 週末は営業時間外
if datetime.now().weekday() >= 5: # 土日
return False
return self.open_time <= check_time <= self.close_time
def next_open_time(self):
"""次の営業開始時間を計算"""
now = datetime.now()
# 今日の営業時間内なら今すぐ
if self.is_open():
return now
# 営業時間後または週末なら次の営業日
next_day = now + timedelta(days=1)
while next_day.weekday() >= 5: # 週末をスキップ
next_day += timedelta(days=1)
return datetime.combine(next_day.date(), self.open_time)
# 使用例
business = BusinessHours("09:00", "18:00")
if business.is_open():
print("現在営業中です")
else:
next_open = business.next_open_time()
print(f"次の営業開始: {next_open.strftime('%Y-%m-%d %H:%M')}")
データ分析での日付処理
from datetime import datetime, timedelta
import csv
class SalesAnalyzer:
def __init__(self):
self.sales_data = []
def add_sale(self, amount, date_str=None):
"""売上データを追加"""
if date_str is None:
sale_date = datetime.now()
else:
sale_date = datetime.strptime(date_str, "%Y-%m-%d")
self.sales_data.append({
'amount': amount,
'date': sale_date
})
def get_sales_by_period(self, days=30):
"""指定期間の売上を取得"""
end_date = datetime.now()
start_date = end_date - timedelta(days=days)
period_sales = []
for sale in self.sales_data:
if start_date <= sale['date'] <= end_date:
period_sales.append(sale)
return period_sales
def monthly_summary(self, year, month):
"""月次売上サマリー"""
monthly_sales = []
total_amount = 0
for sale in self.sales_data:
if sale['date'].year == year and sale['date'].month == month:
monthly_sales.append(sale)
total_amount += sale['amount']
return {
'count': len(monthly_sales),
'total': total_amount,
'average': total_amount / len(monthly_sales) if monthly_sales else 0
}
# 使用例
analyzer = SalesAnalyzer()
analyzer.add_sale(1000, "2024-06-01")
analyzer.add_sale(1500, "2024-06-02")
analyzer.add_sale(800, "2024-05-30")
# 過去30日の売上
recent_sales = analyzer.get_sales_by_period(30)
print(f"過去30日の売上件数: {len(recent_sales)}")
# 6月の売上サマリー
summary = analyzer.monthly_summary(2024, 6)
print(f"6月の売上: {summary}")
タイムゾーンの扱い方
タイムゾーンの基本
from datetime import datetime
from zoneinfo import ZoneInfo # Python 3.9以降
# タイムゾーン付きの日時
tokyo_time = datetime.now(ZoneInfo("Asia/Tokyo"))
utc_time = datetime.now(ZoneInfo("UTC"))
ny_time = datetime.now(ZoneInfo("America/New_York"))
print(f"東京: {tokyo_time}")
print(f"UTC: {utc_time}")
print(f"ニューヨーク: {ny_time}")
Python 3.8以前での対応
from datetime import datetime, timezone, timedelta
# UTCタイムゾーン
utc_time = datetime.now(timezone.utc)
print(f"UTC: {utc_time}")
# 日本標準時(UTC+9)
jst = timezone(timedelta(hours=9))
jst_time = datetime.now(jst)
print(f"JST: {jst_time}")
タイムゾーン変換
from datetime import datetime
from zoneinfo import ZoneInfo
# UTC時刻を他のタイムゾーンに変換
utc_dt = datetime(2024, 6, 2, 12, 0, 0, tzinfo=ZoneInfo("UTC"))
tokyo_dt = utc_dt.astimezone(ZoneInfo("Asia/Tokyo"))
london_dt = utc_dt.astimezone(ZoneInfo("Europe/London"))
print(f"UTC: {utc_dt}")
print(f"東京: {tokyo_dt}")
print(f"ロンドン: {london_dt}")
よくある問題と解決方法

Q1: タイムゾーンなしとありの比較でエラー
症状:
from datetime import datetime
from zoneinfo import ZoneInfo
dt1 = datetime.now() # タイムゾーンなし
dt2 = datetime.now(ZoneInfo("UTC")) # タイムゾーンあり
# これはエラーになる
# diff = dt2 - dt1 # TypeError
解決方法:
# 片方にタイムゾーンを設定
dt1_utc = dt1.replace(tzinfo=ZoneInfo("UTC"))
diff = dt2 - dt1_utc
Q2: 文字列変換でエラー
症状:
# 無効な日付でエラー
datetime.strptime("2024-02-30", "%Y-%m-%d") # ValueError
解決方法:
def safe_strptime(date_string, format_string):
try:
return datetime.strptime(date_string, format_string)
except ValueError:
print(f"無効な日付: {date_string}")
return None
Q3: 月末日の計算
問題:
# 単純に30日を足すと月が変わってしまう可能性
date = datetime(2024, 1, 31)
next_month = date + timedelta(days=30) # 不正確
解決方法:
from calendar import monthrange
def add_months(date, months):
"""月を正確に加算する関数"""
year = date.year
month = date.month + months
# 年の調整
while month > 12:
year += 1
month -= 12
while month < 1:
year -= 1
month += 12
# 月末日の調整
max_day = monthrange(year, month)[1]
day = min(date.day, max_day)
return date.replace(year=year, month=month, day=day)
# 使用例
date = datetime(2024, 1, 31)
next_month = add_months(date, 1)
print(next_month) # 2024-02-29(うるう年の調整)
パフォーマンスと最適化
大量データでの日付処理
from datetime import datetime
import time
# 大量の日付データを処理する場合
dates = ["2024-01-01", "2024-01-02", "2024-01-03"] * 1000
# 毎回strptimeを呼ぶ(遅い)
start = time.time()
for date_str in dates:
dt = datetime.strptime(date_str, "%Y-%m-%d")
slow_time = time.time() - start
# フォーマットをキャッシュする(速い)
start = time.time()
format_str = "%Y-%m-%d"
for date_str in dates:
dt = datetime.strptime(date_str, format_str)
fast_time = time.time() - start
print(f"通常: {slow_time:.4f}秒")
print(f"最適化: {fast_time:.4f}秒")
ISO形式の活用
# ISO形式は高速でパース可能
from datetime import datetime
# ISO形式での処理(推奨)
iso_string = "2024-06-02T14:30:00"
dt = datetime.fromisoformat(iso_string)
# 独自形式(避けたほうが良い)
custom_string = "02/06/2024 2:30 PM"
dt = datetime.strptime(custom_string, "%d/%m/%Y %I:%M %p")
まとめ
Pythonのdatetimeモジュールは、日付と時刻を扱うための強力で柔軟なツールです。
この記事のポイント:
datetime.now()
で現在時刻を取得strftime()
で日時を文字列に変換strptime()
で文字列を日時に変換timedelta
で日時の計算- 実際のアプリケーションでの活用方法
コメント