83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
|
|
# utils/date_converter.py
|
|||
|
|
from datetime import datetime, date
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
class DateConverter:
|
|||
|
|
"""
|
|||
|
|
日本語の日付文字列を扱うユーティリティクラス
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def convert_date(self, date_str: str) -> Optional[date]:
|
|||
|
|
"""
|
|||
|
|
日本語の日付文字列をdateオブジェクトに変換する
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
date_str: 変換する日付文字列(例: '1990年1月1日' or '1990-01-01' or '1990/01/01')
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
変換されたdateオブジェクト。変換できない場合はNone
|
|||
|
|
"""
|
|||
|
|
if not date_str or date_str.strip() == '':
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 全角数字を半角数字に変換
|
|||
|
|
date_str = date_str.translate(
|
|||
|
|
str.maketrans('0123456789', '0123456789')
|
|||
|
|
)
|
|||
|
|
date_str = date_str.strip()
|
|||
|
|
|
|||
|
|
# 区切り文字の判定と分割
|
|||
|
|
if '年' in date_str:
|
|||
|
|
# 年月日形式の場合
|
|||
|
|
date_parts = date_str.replace('年', '/').replace('月', '/').replace('日', '').split('/')
|
|||
|
|
elif '/' in date_str:
|
|||
|
|
# スラッシュ区切りの場合
|
|||
|
|
date_parts = date_str.split('/')
|
|||
|
|
elif '-' in date_str:
|
|||
|
|
# ハイフン区切りの場合
|
|||
|
|
date_parts = date_str.split('-')
|
|||
|
|
else:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
# 部分の数を確認
|
|||
|
|
if len(date_parts) != 3:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
year = int(date_parts[0])
|
|||
|
|
month = int(date_parts[1])
|
|||
|
|
day = int(date_parts[2])
|
|||
|
|
|
|||
|
|
# 簡単な妥当性チェック
|
|||
|
|
if not (1900 <= year <= 2100):
|
|||
|
|
return None
|
|||
|
|
if not (1 <= month <= 12):
|
|||
|
|
return None
|
|||
|
|
if not (1 <= day <= 31):
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
return date(year, month, day)
|
|||
|
|
|
|||
|
|
except (ValueError, IndexError, TypeError):
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def format_date(self, d: date, format_type: str = 'ja') -> str:
|
|||
|
|
"""
|
|||
|
|
dateオブジェクトを指定された形式の文字列に変換する
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
d: 変換するdateオブジェクト
|
|||
|
|
format_type: 出力形式 ('ja': 日本語形式, 'iso': ISO形式)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
変換された日付文字列
|
|||
|
|
"""
|
|||
|
|
if not isinstance(d, date):
|
|||
|
|
return ''
|
|||
|
|
|
|||
|
|
if format_type == 'ja':
|
|||
|
|
return f"{d.year}年{d.month}月{d.day}日"
|
|||
|
|
elif format_type == 'iso':
|
|||
|
|
return d.isoformat()
|
|||
|
|
else:
|
|||
|
|
return str(d)
|