Files
bakery-ia/shared/dt_utils/core.py
2025-10-12 23:16:04 +02:00

169 lines
3.4 KiB
Python

"""
Core DateTime Utilities
Low-level datetime operations for the bakery system.
All functions use Python's built-in zoneinfo for timezone handling.
"""
from datetime import datetime, timezone
from typing import Optional
from zoneinfo import ZoneInfo
from .constants import DEFAULT_TIMEZONE, ISO_FORMAT
def utc_now() -> datetime:
"""
Get current datetime in UTC with timezone awareness.
Returns:
Current UTC datetime
"""
return datetime.now(timezone.utc)
def now_in_timezone(tz: str = DEFAULT_TIMEZONE) -> datetime:
"""
Get current datetime in specified timezone.
Args:
tz: IANA timezone string (e.g., "Europe/Madrid")
Returns:
Current datetime in the specified timezone
"""
return datetime.now(ZoneInfo(tz))
def to_utc(dt: datetime) -> datetime:
"""
Convert datetime to UTC.
Args:
dt: Datetime to convert (if naive, assumes UTC)
Returns:
Datetime in UTC timezone
"""
if dt.tzinfo is None:
return dt.replace(tzinfo=timezone.utc)
return dt.astimezone(timezone.utc)
def to_timezone(dt: datetime, tz: str) -> datetime:
"""
Convert datetime to specified timezone.
Args:
dt: Datetime to convert (if naive, assumes UTC)
tz: Target IANA timezone string
Returns:
Datetime in target timezone
"""
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return dt.astimezone(ZoneInfo(tz))
def ensure_aware(dt: datetime, default_tz: str = "UTC") -> datetime:
"""
Ensure a datetime is timezone-aware.
Args:
dt: Datetime to check
default_tz: Timezone to apply if datetime is naive (default: UTC)
Returns:
Timezone-aware datetime
"""
if dt.tzinfo is None:
tz = ZoneInfo(default_tz)
return dt.replace(tzinfo=tz)
return dt
def ensure_naive(dt: datetime) -> datetime:
"""
Remove timezone information from a datetime.
Args:
dt: Datetime to process
Returns:
Timezone-naive datetime
"""
if dt.tzinfo is not None:
return dt.replace(tzinfo=None)
return dt
def parse_iso(dt_str: str) -> datetime:
"""
Parse ISO format datetime string.
Args:
dt_str: ISO format datetime string
Returns:
Parsed datetime (timezone-aware if timezone info present)
"""
return datetime.fromisoformat(dt_str)
def format_iso(dt: datetime) -> str:
"""
Format datetime as ISO string.
Args:
dt: Datetime to format
Returns:
ISO format string
"""
return dt.isoformat()
def format_custom(dt: datetime, format_str: str = ISO_FORMAT) -> str:
"""
Format datetime with custom format string.
Args:
dt: Datetime to format
format_str: strftime format string
Returns:
Formatted datetime string
"""
return dt.strftime(format_str)
def is_aware(dt: datetime) -> bool:
"""
Check if datetime is timezone-aware.
Args:
dt: Datetime to check
Returns:
True if timezone-aware, False otherwise
"""
return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
def validate_timezone(tz: str) -> bool:
"""
Validate if timezone string is valid.
Args:
tz: IANA timezone string to validate
Returns:
True if valid, False otherwise
"""
try:
ZoneInfo(tz)
return True
except Exception:
return False