hesabixArc/hesabixAPI/app/core/calendar.py

92 lines
3.3 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Literal, Optional
import jdatetime
CalendarType = Literal["gregorian", "jalali"]
class CalendarConverter:
"""Utility class for converting dates between Gregorian and Jalali calendars"""
@staticmethod
def to_jalali(dt: datetime) -> dict:
"""Convert Gregorian datetime to Jalali format"""
if dt is None:
return None
jalali = jdatetime.datetime.fromgregorian(datetime=dt)
# نام ماه‌های شمسی
jalali_month_names = [
'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور',
'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
]
# نام روزهای هفته شمسی
jalali_weekday_names = [
'شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه'
]
return {
"year": jalali.year,
"month": jalali.month,
"day": jalali.day,
"hour": jalali.hour,
"minute": jalali.minute,
"second": jalali.second,
"weekday": jalali.weekday(),
"month_name": jalali_month_names[jalali.month - 1],
"weekday_name": jalali_weekday_names[jalali.weekday()],
"formatted": jalali.strftime("%Y/%m/%d %H:%M:%S"),
"date_only": jalali.strftime("%Y/%m/%d"),
"time_only": jalali.strftime("%H:%M:%S"),
"is_leap_year": jalali.isleap(),
"month_days": jdatetime.j_days_in_month[jalali.month - 1],
}
@staticmethod
def to_gregorian(dt: datetime) -> dict:
"""Convert Gregorian datetime to standard format"""
if dt is None:
return None
return {
"year": dt.year,
"month": dt.month,
"day": dt.day,
"hour": dt.hour,
"minute": dt.minute,
"second": dt.second,
"weekday": dt.weekday(),
"month_name": dt.strftime("%B"),
"weekday_name": dt.strftime("%A"),
"formatted": dt.strftime("%Y-%m-%d %H:%M:%S"),
"date_only": dt.strftime("%Y-%m-%d"),
"time_only": dt.strftime("%H:%M:%S"),
}
@staticmethod
def format_datetime(dt: datetime, calendar_type: CalendarType) -> dict:
"""Format datetime based on calendar type"""
if calendar_type == "jalali":
return CalendarConverter.to_jalali(dt)
else:
return CalendarConverter.to_gregorian(dt)
@staticmethod
def format_datetime_list(dt_list: list[datetime], calendar_type: CalendarType) -> list[dict]:
"""Format list of datetimes based on calendar type"""
return [CalendarConverter.format_datetime(dt, calendar_type) for dt in dt_list if dt is not None]
def get_calendar_type_from_header(calendar_header: Optional[str]) -> CalendarType:
"""Extract calendar type from X-Calendar-Type header"""
if not calendar_header:
return "gregorian"
calendar_type = calendar_header.lower().strip()
if calendar_type in ["jalali", "persian", "shamsi"]:
return "jalali"
else:
return "gregorian"