Refactor datetime and timezone utils
This commit is contained in:
168
shared/dt_utils/core.py
Normal file
168
shared/dt_utils/core.py
Normal file
@@ -0,0 +1,168 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user