Pythonで「今の日付(年月日)を取得したい!」という場面は、ログの記録やファイル名の自動生成など、実務でもよく出てきます。
しかし、初心者にとってはどのモジュールを使えばよいのか、どのような書き方が最適なのか悩むところです。
この記事では、Pythonでの年月日(Year, Month, Day)を取得する基本的な方法を、サンプルコードと一緒にわかりやすく紹介します。
方法1:datetimeモジュールの基本使用

最も基本的な日付取得
datetime
モジュールは、Pythonで日時を扱う際の標準的な選択肢です。
基本的な使い方:
from datetime import datetime
# 現在の日時を取得
today = datetime.today()
print(today)
# 出力例: 2025-06-20 14:33:25.123456
# より正確な現在時刻を取得
now = datetime.now()
print(now)
# 出力例: 2025-06-20 14:33:25.123456
datetime.today()とdatetime.now()の違い:
メソッド | 説明 | 用途 |
---|---|---|
datetime.today() | ローカル時刻を取得 | 一般的な日付取得 |
datetime.now() | より正確な現在時刻 | タイムスタンプが重要な場合 |
datetime.now(tz) | タイムゾーン指定可能 | 国際的なアプリケーション |
年・月・日の個別取得
from datetime import datetime
today = datetime.today()
# 個別に年月日を取得
year = today.year
month = today.month
day = today.day
print(f"年: {year}")
print(f"月: {month}")
print(f"日: {day}")
# 出力例:
# 年: 2025
# 月: 6
# 日: 20
# 曜日情報も取得可能
weekday = today.weekday() # 0=月曜日, 6=日曜日
weekday_name = today.strftime("%A")
print(f"曜日番号: {weekday}")
print(f"曜日名: {weekday_name}")
実用的な活用例
ファイル名の自動生成:
from datetime import datetime
def create_log_filename():
"""現在の日時を使ってログファイル名を生成"""
now = datetime.now()
filename = f"log_{now.year}{now.month:02d}{now.day:02d}_{now.hour:02d}{now.minute:02d}.txt"
return filename
# 使用例
log_file = create_log_filename()
print(f"ログファイル名: {log_file}")
# 出力例: log_20250620_1433.txt
データベース用のタイムスタンプ:
from datetime import datetime
def get_timestamp_for_db():
"""データベース用のタイムスタンプを生成"""
return datetime.now().isoformat()
# 使用例
timestamp = get_timestamp_for_db()
print(f"DBタイムスタンプ: {timestamp}")
# 出力例: 2025-06-20T14:33:25.123456
年・月・日を個別に取り出せるので、ファイル名やタイトルへの埋め込みに非常に便利です。次は、時間情報が不要な場合のより簡潔な方法を見ていきましょう。
方法2:dateモジュールでシンプルな日付取得

時間なしの日付のみ取得
時刻情報が不要で、日付だけを扱いたい場合はdate
クラスが最適です。
基本的な使い方:
from datetime import date
# 今日の日付を取得
today = date.today()
print(today)
# 出力例: 2025-06-20
# 年月日の個別取得
print(f"年: {today.year}") # 2025
print(f"月: {today.month}") # 6
print(f"日: {today.day}") # 20
# 曜日の取得
print(f"曜日番号: {today.weekday()}") # 0=月曜日, 6=日曜日
print(f"ISO曜日: {today.isoweekday()}") # 1=月曜日, 7=日曜日
dateとdatetimeの使い分け
dateクラスの特徴:
- メモリ使用量が少ない
- 時刻情報を持たない
- 日付の比較や計算がシンプル
- データベースのDATE型との親和性
実用的な比較例:
from datetime import date, datetime
import sys
# メモリ使用量の比較
date_obj = date.today()
datetime_obj = datetime.now()
print(f"dateオブジェクトのサイズ: {sys.getsizeof(date_obj)} bytes")
print(f"datetimeオブジェクトのサイズ: {sys.getsizeof(datetime_obj)} bytes")
# 出力例:
# dateオブジェクトのサイズ: 32 bytes
# datetimeオブジェクトのサイズ: 48 bytes
実用的な活用例
日付ベースのディレクトリ作成:
from datetime import date
import os
def create_daily_directory():
"""今日の日付でディレクトリを作成"""
today = date.today()
dir_name = f"data_{today.year}_{today.month:02d}_{today.day:02d}"
if not os.path.exists(dir_name):
os.makedirs(dir_name)
print(f"ディレクトリを作成しました: {dir_name}")
else:
print(f"ディレクトリは既に存在します: {dir_name}")
return dir_name
# 使用例
daily_dir = create_daily_directory()
# 出力例: ディレクトリを作成しました: data_2025_06_20
年齢計算の例:
from datetime import date
def calculate_age(birth_date):
"""生年月日から年齢を計算"""
today = date.today()
age = today.year - birth_date.year
# 誕生日がまだ来ていない場合は1歳引く
if today.month < birth_date.month or \
(today.month == birth_date.month and today.day < birth_date.day):
age -= 1
return age
# 使用例
birth = date(1990, 3, 15)
age = calculate_age(birth)
print(f"年齢: {age}歳")
「時刻は不要で、日付だけ欲しい」という場面では、この方法がメモリ効率的でシンプルです。
次は、取得した日付を様々な形式で表示する方法を学びましょう。
方法3:文字列フォーマットによる表示形式の制御

strftimeによる書式指定
取得した日付を特定の形式で表示したい場合、strftime
メソッドが非常に便利です。
基本的な書式指定:
from datetime import datetime
now = datetime.now()
# さまざまなフォーマットで表示
print("基本形式:", now.strftime("%Y/%m/%d")) # 2025/06/20
print("日本式:", now.strftime("%Y年%m月%d日")) # 2025年06月20日
print("英語式:", now.strftime("%B %d, %Y")) # June 20, 2025
print("時刻付き:", now.strftime("%Y-%m-%d %H:%M:%S")) # 2025-06-20 14:33:25
print("12時間表示:", now.strftime("%Y/%m/%d %I:%M %p")) # 2025/06/20 02:33 PM
主要な書式指定子一覧
書式 | 意味 | 出力例 | 説明 |
---|---|---|---|
%Y | 年(4桁) | 2025 | 西暦年 |
%y | 年(2桁) | 25 | 西暦年の下2桁 |
%m | 月(2桁) | 06 | ゼロ埋めあり |
%d | 日(2桁) | 20 | ゼロ埋めあり |
%B | 月名(英語) | June | 完全な月名 |
%b | 月名(英語短縮) | Jun | 3文字の月名 |
%A | 曜日名(英語) | Friday | 完全な曜日名 |
%a | 曜日名(英語短縮) | Fri | 3文字の曜日名 |
%H | 時(24時間) | 14 | 00-23の範囲 |
%I | 時(12時間) | 02 | 01-12の範囲 |
%M | 分 | 33 | 00-59の範囲 |
%S | 秒 | 25 | 00-59の範囲 |
%p | AM/PM | PM | 午前/午後 |
実用的なフォーマット例
ログファイル用のタイムスタンプ:
from datetime import datetime
def create_log_entry(message):
"""ログエントリを作成"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return f"[{timestamp}] {message}"
# 使用例
log_entry = create_log_entry("システム開始")
print(log_entry)
# 出力例: [2025-06-20 14:33:25] システム開始
レポート用の日付表示:
from datetime import datetime
def format_report_date():
"""レポート用の日付フォーマット"""
now = datetime.now()
# 複数のフォーマットを返す
formats = {
'iso': now.strftime("%Y-%m-%d"),
'japanese': now.strftime("%Y年%m月%d日"),
'english': now.strftime("%B %d, %Y"),
'compact': now.strftime("%Y%m%d"),
'timestamp': now.strftime("%Y%m%d_%H%M%S")
}
return formats
# 使用例
date_formats = format_report_date()
for format_name, formatted_date in date_formats.items():
print(f"{format_name}: {formatted_date}")
# 出力例:
# iso: 2025-06-20
# japanese: 2025年06月20日
# english: June 20, 2025
# compact: 20250620
# timestamp: 20250620_143325
国際化対応の日付表示:
from datetime import datetime
import locale
def format_localized_date():
"""ロケール対応の日付フォーマット"""
now = datetime.now()
try:
# 日本語ロケールを設定(環境によって異なる)
locale.setlocale(locale.LC_TIME, 'ja_JP.UTF-8')
japanese_date = now.strftime("%Y年%m月%d日 (%A)")
except locale.Error:
# ロケールが設定できない場合は英語のまま
japanese_date = now.strftime("%Y年%m月%d日 (%A)")
return japanese_date
# 使用例
localized_date = format_localized_date()
print(f"ローカライズ日付: {localized_date}")
実用的な応用例とベストプラクティス

ファイル管理での活用
自動バックアップシステム:
from datetime import datetime, date
import shutil
import os
class BackupManager:
"""日付ベースのバックアップ管理クラス"""
def __init__(self, source_dir, backup_dir):
self.source_dir = source_dir
self.backup_dir = backup_dir
def create_backup(self):
"""現在の日時でバックアップを作成"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_name = f"backup_{timestamp}"
backup_path = os.path.join(self.backup_dir, backup_name)
try:
shutil.copytree(self.source_dir, backup_path)
print(f"バックアップ作成完了: {backup_path}")
return backup_path
except Exception as e:
print(f"バックアップエラー: {e}")
return None
def cleanup_old_backups(self, keep_days=7):
"""古いバックアップを削除"""
cutoff_date = date.today().replace(day=date.today().day - keep_days)
for item in os.listdir(self.backup_dir):
if item.startswith("backup_"):
# ファイル名から日付を抽出
try:
date_str = item.split("_")[1][:8] # YYYYMMDD
backup_date = datetime.strptime(date_str, "%Y%m%d").date()
if backup_date < cutoff_date:
backup_path = os.path.join(self.backup_dir, item)
shutil.rmtree(backup_path)
print(f"古いバックアップを削除: {item}")
except Exception as e:
print(f"バックアップ削除エラー: {e}")
# 使用例
backup_manager = BackupManager("/path/to/source", "/path/to/backups")
backup_manager.create_backup()
backup_manager.cleanup_old_backups()
データ分析での活用
日次レポート生成:
from datetime import datetime, timedelta
import pandas as pd
class DailyReportGenerator:
"""日次レポート生成クラス"""
def __init__(self):
self.report_date = datetime.now().date()
def generate_filename(self):
"""レポートファイル名を生成"""
date_str = self.report_date.strftime("%Y%m%d")
return f"daily_report_{date_str}.xlsx"
def get_date_range(self, days_back=7):
"""指定日数前からの日付範囲を取得"""
end_date = self.report_date
start_date = end_date - timedelta(days=days_back)
date_range = []
current_date = start_date
while current_date <= end_date:
date_range.append(current_date)
current_date += timedelta(days=1)
return date_range
def create_report_header(self):
"""レポートヘッダーを作成"""
formatted_date = self.report_date.strftime("%Y年%m月%d日")
weekday = self.report_date.strftime("%A")
header = {
'report_date': formatted_date,
'weekday': weekday,
'generated_at': datetime.now().isoformat(),
'report_type': '日次売上レポート'
}
return header
# 使用例
report_gen = DailyReportGenerator()
filename = report_gen.generate_filename()
date_range = report_gen.get_date_range()
header = report_gen.create_report_header()
print(f"レポートファイル名: {filename}")
print(f"対象期間: {len(date_range)}日間")
print(f"レポートヘッダー: {header}")
Webアプリケーションでの活用
イベント管理システム:
from datetime import datetime, date, timedelta
class EventManager:
"""イベント管理クラス"""
def __init__(self):
self.events = []
def add_event(self, title, event_date, description=""):
"""イベントを追加"""
event = {
'id': len(self.events) + 1,
'title': title,
'event_date': event_date,
'description': description,
'created_at': datetime.now(),
'status': self.get_event_status(event_date)
}
self.events.append(event)
return event
def get_event_status(self, event_date):
"""イベントの状態を判定"""
today = date.today()
if event_date < today:
return "終了"
elif event_date == today:
return "本日開催"
elif event_date <= today + timedelta(days=7):
return "間もなく開催"
else:
return "開催予定"
def get_upcoming_events(self, days=30):
"""今後のイベントを取得"""
cutoff_date = date.today() + timedelta(days=days)
upcoming = [
event for event in self.events
if event['event_date'] >= date.today()
and event['event_date'] <= cutoff_date
]
return sorted(upcoming, key=lambda x: x['event_date'])
def format_event_list(self, events):
"""イベントリストを整形"""
if not events:
return "予定されているイベントはありません。"
formatted_list = []
for event in events:
date_str = event['event_date'].strftime("%Y年%m月%d日 (%A)")
formatted_list.append(
f"・{event['title']} - {date_str} [{event['status']}]"
)
return "\n".join(formatted_list)
# 使用例
event_mgr = EventManager()
# イベントを追加
event_mgr.add_event("チーム会議", date.today() + timedelta(days=1))
event_mgr.add_event("プロジェクト発表", date.today() + timedelta(days=14))
event_mgr.add_event("年末パーティー", date(2025, 12, 25))
# 今後のイベントを表示
upcoming = event_mgr.get_upcoming_events()
formatted_events = event_mgr.format_event_list(upcoming)
print("今後のイベント:")
print(formatted_events)
高度な日付処理とエラーハンドリング

タイムゾーン対応
タイムゾーンを考慮した日付取得:
from datetime import datetime, timezone, timedelta
import pytz # pip install pytz が必要
def get_timezone_aware_date():
"""タイムゾーンを考慮した日付取得"""
# UTC時刻
utc_now = datetime.now(timezone.utc)
print(f"UTC時刻: {utc_now}")
# 日本時刻(JST)
jst = timezone(timedelta(hours=9))
jst_now = datetime.now(jst)
print(f"JST時刻: {jst_now}")
# pytzを使用した方法(より多くのタイムゾーンに対応)
tokyo_tz = pytz.timezone('Asia/Tokyo')
tokyo_now = datetime.now(tokyo_tz)
print(f"東京時刻: {tokyo_now}")
return {
'utc': utc_now,
'jst': jst_now,
'tokyo': tokyo_now
}
# 使用例
timezone_dates = get_timezone_aware_date()
エラーハンドリング
安全な日付処理:
from datetime import datetime, date
import logging
class SafeDateHandler:
"""安全な日付処理クラス"""
def __init__(self):
self.logger = logging.getLogger(__name__)
def safe_parse_date(self, date_string, format_string="%Y-%m-%d"):
"""文字列を安全に日付に変換"""
try:
return datetime.strptime(date_string, format_string).date()
except ValueError as e:
self.logger.error(f"日付変換エラー: {date_string}, {e}")
return None
def safe_format_date(self, date_obj, format_string="%Y/%m/%d"):
"""日付を安全に文字列に変換"""
try:
if isinstance(date_obj, (date, datetime)):
return date_obj.strftime(format_string)
else:
raise TypeError("date または datetime オブジェクトが必要です")
except Exception as e:
self.logger.error(f"日付フォーマットエラー: {date_obj}, {e}")
return None
def validate_date_range(self, start_date, end_date):
"""日付範囲の妥当性を検証"""
try:
if not isinstance(start_date, (date, datetime)):
start_date = self.safe_parse_date(str(start_date))
if not isinstance(end_date, (date, datetime)):
end_date = self.safe_parse_date(str(end_date))
if start_date and end_date:
if start_date <= end_date:
return True, "有効な日付範囲です"
else:
return False, "開始日が終了日より後になっています"
else:
return False, "日付の解析に失敗しました"
except Exception as e:
self.logger.error(f"日付範囲検証エラー: {e}")
return False, f"検証エラー: {e}"
# 使用例
date_handler = SafeDateHandler()
# 安全な日付変換
parsed_date = date_handler.safe_parse_date("2025-06-20")
formatted_date = date_handler.safe_format_date(parsed_date, "%Y年%m月%d日")
print(f"変換結果: {formatted_date}")
# 日付範囲の検証
is_valid, message = date_handler.validate_date_range("2025-06-01", "2025-06-30")
print(f"範囲検証: {is_valid}, {message}")
パフォーマンスとベストプラクティス
効率的な日付処理
大量データでの日付処理最適化:
from datetime import datetime, date
import time
def benchmark_date_operations():
"""日付操作のベンチマーク"""
# テスト用のデータ準備
test_count = 100000
# datetime.now() vs datetime.today()
start_time = time.time()
for _ in range(test_count):
dt = datetime.now()
now_time = time.time() - start_time
start_time = time.time()
for _ in range(test_count):
dt = datetime.today()
today_time = time.time() - start_time
# date.today() のパフォーマンス
start_time = time.time()
for _ in range(test_count):
d = date.today()
date_time = time.time() - start_time
print(f"datetime.now(): {now_time:.4f}秒")
print(f"datetime.today(): {today_time:.4f}秒")
print(f"date.today(): {date_time:.4f}秒")
return {
'datetime_now': now_time,
'datetime_today': today_time,
'date_today': date_time
}
# 使用例
benchmark_results = benchmark_date_operations()
メモリ効率的な日付処理:
from datetime import date, datetime
import sys
def compare_memory_usage():
"""日付オブジェクトのメモリ使用量比較"""
# 異なる日付オブジェクトのメモリ使用量
date_obj = date.today()
datetime_obj = datetime.now()
date_string = str(date_obj)
print(f"date object: {sys.getsizeof(date_obj)} bytes")
print(f"datetime object: {sys.getsizeof(datetime_obj)} bytes")
print(f"date string: {sys.getsizeof(date_string)} bytes")
# 大量の日付オブジェクトを扱う場合の推奨事項
print("\n推奨事項:")
print("- 時刻が不要な場合は date を使用")
print("- 文字列での保存は必要最小限に")
print("- タイムスタンプが必要な場合のみ datetime を使用")
# 使用例
compare_memory_usage()
まとめ:効率的な日付処理のガイド
用途別の推奨方法
用途 | 推奨メソッド | 理由 |
---|---|---|
ログのタイムスタンプ | datetime.now() | 精密な時刻情報が必要 |
ファイル名の日付 | date.today() | シンプルで軽量 |
データベース保存 | datetime.now().isoformat() | 標準形式で互換性が高い |
ユーザー表示 | strftime() | 読みやすい形式に変換 |
期間計算 | date.today() | 計算処理が軽量 |
開発効率を上げるコツ
よく使うフォーマットの関数化:
from datetime import datetime, date
class DateUtils:
"""日付ユーティリティクラス"""
@staticmethod
def get_today_string():
"""今日の日付を文字列で取得"""
return date.today().strftime("%Y-%m-%d")
@staticmethod
def get_timestamp():
"""現在のタイムスタンプを取得"""
return datetime.now().strftime("%Y%m%d_%H%M%S")
@staticmethod
def get_japanese_date():
"""日本語形式の日付を取得"""
return date.today().strftime("%Y年%m月%d日")
@staticmethod
def get_iso_datetime():
"""ISO形式の日時を取得"""
return datetime.now().isoformat()
@staticmethod
def get_log_timestamp():
"""ログ用のタイムスタンプを取得"""
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 使用例
print("今日の日付:", DateUtils.get_today_string())
print("タイムスタンプ:", DateUtils.get_timestamp())
print("日本語日付:", DateUtils.get_japanese_date())
print("ISO形式:", DateUtils.get_iso_datetime())
print("ログ形式:", DateUtils.get_log_timestamp())
# 出力例:
# 今日の日付: 2025-06-20
# タイムスタンプ: 20250620_143325
# 日本語日付: 2025年06月20日
# ISO形式: 2025-06-20T14:33:25.123456
# ログ形式: 2025-06-20 14:33:25
設定ファイルでの日付フォーマット管理
設定可能な日付フォーマット:
import json
from datetime import datetime, date
class ConfigurableDateFormatter:
"""設定可能な日付フォーマッタ"""
def __init__(self, config_file="date_config.json"):
self.config = self.load_config(config_file)
def load_config(self, config_file):
"""設定ファイルを読み込み"""
default_config = {
"date_formats": {
"default": "%Y-%m-%d",
"japanese": "%Y年%m月%d日",
"us": "%m/%d/%Y",
"european": "%d/%m/%Y",
"iso": "%Y-%m-%d",
"compact": "%Y%m%d"
},
"datetime_formats": {
"default": "%Y-%m-%d %H:%M:%S",
"iso": "%Y-%m-%dT%H:%M:%S",
"log": "[%Y-%m-%d %H:%M:%S]",
"filename": "%Y%m%d_%H%M%S"
}
}
try:
with open(config_file, 'r') as f:
config = json.load(f)
return {**default_config, **config}
except FileNotFoundError:
return default_config
def format_date(self, date_obj=None, format_name="default"):
"""設定に基づいて日付をフォーマット"""
if date_obj is None:
date_obj = date.today()
format_string = self.config["date_formats"].get(format_name, "%Y-%m-%d")
return date_obj.strftime(format_string)
def format_datetime(self, datetime_obj=None, format_name="default"):
"""設定に基づいて日時をフォーマット"""
if datetime_obj is None:
datetime_obj = datetime.now()
format_string = self.config["datetime_formats"].get(format_name, "%Y-%m-%d %H:%M:%S")
return datetime_obj.strftime(format_string)
# 使用例
formatter = ConfigurableDateFormatter()
# 様々な形式で現在の日付を表示
formats = ["default", "japanese", "us", "european", "compact"]
for fmt in formats:
formatted = formatter.format_date(format_name=fmt)
print(f"{fmt}: {formatted}")
# 出力例:
# default: 2025-06-20
# japanese: 2025年06月20日
# us: 06/20/2025
# european: 20/06/2025
# compact: 20250620
国際化対応の日付処理
多言語対応の日付表示:
from datetime import datetime, date
import calendar
import locale
class InternationalDateFormatter:
"""国際化対応の日付フォーマッタ"""
def __init__(self):
self.month_names = {
'en': ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'],
'ja': ['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月'],
'fr': ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']
}
self.weekday_names = {
'en': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
'ja': ['月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日'],
'fr': ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche']
}
def format_date_localized(self, date_obj=None, lang='en'):
"""ローカライズされた日付フォーマット"""
if date_obj is None:
date_obj = date.today()
if lang not in self.month_names:
lang = 'en'
month_name = self.month_names[lang][date_obj.month - 1]
weekday_name = self.weekday_names[lang][date_obj.weekday()]
if lang == 'ja':
return f"{date_obj.year}年{month_name}{date_obj.day}日 ({weekday_name})"
elif lang == 'en':
return f"{weekday_name}, {month_name} {date_obj.day}, {date_obj.year}"
elif lang == 'fr':
return f"{weekday_name} {date_obj.day} {month_name} {date_obj.year}"
return str(date_obj)
def get_all_formats(self, date_obj=None):
"""全ての言語形式で日付を取得"""
if date_obj is None:
date_obj = date.today()
formats = {}
for lang in self.month_names.keys():
formats[lang] = self.format_date_localized(date_obj, lang)
return formats
# 使用例
intl_formatter = InternationalDateFormatter()
all_formats = intl_formatter.get_all_formats()
for lang, formatted_date in all_formats.items():
print(f"{lang}: {formatted_date}")
# 出力例:
# en: Friday, June 20, 2025
# ja: 2025年6月20日 (金曜日)
# fr: vendredi 20 juin 2025
エラーハンドリングのベストプラクティス
堅牢な日付処理システム:
from datetime import datetime, date
import logging
from typing import Optional, Union
class RobustDateProcessor:
"""堅牢な日付処理クラス"""
def __init__(self):
self.logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
def safe_date_operation(self, operation, *args, **kwargs):
"""安全な日付操作の実行"""
try:
return operation(*args, **kwargs), None
except Exception as e:
error_msg = f"日付操作エラー: {e}"
self.logger.error(error_msg)
return None, error_msg
def parse_flexible_date(self, date_input: Union[str, date, datetime]) -> Optional[date]:
"""柔軟な日付パース"""
if isinstance(date_input, date):
return date_input
elif isinstance(date_input, datetime):
return date_input.date()
elif isinstance(date_input, str):
# 複数のフォーマットを試行
formats = [
"%Y-%m-%d",
"%Y/%m/%d",
"%d/%m/%Y",
"%m/%d/%Y",
"%Y%m%d",
"%d-%m-%Y"
]
for fmt in formats:
try:
return datetime.strptime(date_input, fmt).date()
except ValueError:
continue
self.logger.error(f"日付パースに失敗: {date_input}")
return None
else:
self.logger.error(f"サポートされていない日付形式: {type(date_input)}")
return None
def calculate_business_days(self, start_date: Union[str, date],
end_date: Union[str, date]) -> Optional[int]:
"""営業日数の計算"""
start = self.parse_flexible_date(start_date)
end = self.parse_flexible_date(end_date)
if not start or not end:
return None
if start > end:
start, end = end, start
business_days = 0
current_date = start
while current_date <= end:
if current_date.weekday() < 5: # 月曜日=0, 日曜日=6
business_days += 1
current_date = current_date.replace(day=current_date.day + 1)
return business_days
def format_with_fallback(self, date_obj: Union[str, date, datetime],
primary_format: str,
fallback_format: str = "%Y-%m-%d") -> str:
"""フォールバック付きフォーマット"""
parsed_date = self.parse_flexible_date(date_obj)
if not parsed_date:
return "Invalid Date"
try:
return parsed_date.strftime(primary_format)
except ValueError:
self.logger.warning(f"プライマリフォーマット失敗: {primary_format}")
try:
return parsed_date.strftime(fallback_format)
except ValueError:
return str(parsed_date)
# 使用例
processor = RobustDateProcessor()
# 柔軟な日付パース
test_dates = ["2025-06-20", "20/06/2025", "06/20/2025", "20250620"]
for test_date in test_dates:
parsed = processor.parse_flexible_date(test_date)
print(f"{test_date} → {parsed}")
# 営業日数計算
business_days = processor.calculate_business_days("2025-06-01", "2025-06-30")
print(f"営業日数: {business_days}日")
# フォールバック付きフォーマット
formatted = processor.format_with_fallback(
date.today(),
"%Y年%m月%d日 (%A)", # プライマリ
"%Y-%m-%d" # フォールバック
)
print(f"フォーマット結果: {formatted}")
コメント