Spaces:
Running
Running
| from __future__ import annotations | |
| """Datetime utility helpers.""" | |
| from datetime import datetime, timedelta, timezone | |
| from typing import Optional, Union | |
| JST = timezone(timedelta(hours=9)) | |
| def normalize_to_jst_string(value: Optional[Union[str, datetime]]) -> str: | |
| """Convert various datetime representations into JST string (YYYY-MM-DD HH:MM:SS). | |
| If the value is None/empty or cannot be parsed, returns 'N/A'. | |
| """ | |
| if value is None: | |
| return "N/A" | |
| if isinstance(value, datetime): | |
| dt = value | |
| else: | |
| s = str(value).strip() | |
| if not s or s.lower() in {"nan", "n/a", "none"}: | |
| return "N/A" | |
| try: | |
| dt = datetime.fromisoformat(s.replace("Z", "+00:00")) | |
| except ValueError: | |
| try: | |
| dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S") | |
| except ValueError: | |
| return "N/A" | |
| if dt.tzinfo is None: | |
| # Assume already JST when timezone-less | |
| dt = dt.replace(tzinfo=JST) | |
| else: | |
| dt = dt.astimezone(JST) | |
| return dt.strftime("%Y-%m-%d %H:%M:%S") | |