arconverter.arconverter
Convert dates to Absolom Reconing calendar system.
Examples:
from datetime import datetime date = datetime(2023, 12, 25) ar_date = convert(date) print(ar_date.year) # 4723
1"""Convert dates to Absolom Reconing calendar system. 2 3Examples: 4 >>> from datetime import datetime 5 >>> date = datetime(2023, 12, 25) 6 >>> ar_date = convert(date) 7 >>> print(ar_date.year) # 4723 8""" 9 10from datetime import datetime 11from typing import Final 12 13from arconverter.ardate import ArDate 14from arconverter.constants import ( 15 arCommonMonths, 16 arDays, 17 arDayShort, 18 arMonths, 19 arMonthSeasons, 20 arShortMonths, 21) 22 23MIN_YEAR: Final[int] = 1970 # Unix epoch 24MAX_YEAR: Final[int] = 2099 # Upper limit before conversion breaks 25 26YEAR_OFFSET: Final[int] = 2700 # Set by the Absolom Reckoning calendar (Paizo) 27 28 29class ArConverterError(Exception): 30 """Base exception for arconverter errors.""" 31 32 pass 33 34 35def validate_date(date: datetime) -> None: 36 """Validate the input date is within acceptable ranges.""" 37 if not isinstance(date, datetime): 38 raise ArConverterError('Input must be a datetime object') 39 40 if date.year < MIN_YEAR or date.year > MAX_YEAR: 41 raise ArConverterError(f'Year must be between {MIN_YEAR} and {MAX_YEAR}') 42 43 44def convert(target_date: datetime) -> ArDate: 45 """Convert a datetime object to an Absalom Reckoning date. 46 47 Args: 48 target_date: A datetime object representing the Gregorian calendar date to convert 49 50 Returns: 51 ArDate: An Absalom Reckoning date object with the following attributes: 52 - year: AR year (Gregorian + 2700) 53 - month: Full month name 54 - monthShort: 3-letter month abbreviation 55 - commonMonth: Common folk month name 56 - day: Day of month 57 - weekday: Full weekday name 58 - weekdayShort: 3-letter weekday abbreviation 59 - weekdayNum: Day of week (1-7, Moonday=1) 60 - monthNum: Month number (1-12) 61 - season: Current season name 62 63 Raises: 64 ArConverterError: If input is not a datetime object or year is out of valid range 65 66 Examples: 67 >>> from datetime import datetime 68 >>> date = datetime(2023, 7, 10) 69 >>> ar_date = convert(date) 70 >>> print(ar_date.long_date()) 71 'Erastus 10, 4723' 72 >>> print(ar_date.season) 73 'Summer' 74 """ 75 validate_date(target_date) 76 77 try: 78 # Break the year up into pieces 79 year = target_date.year 80 month = target_date.month 81 day = target_date.day 82 day_of_week = target_date.weekday() + 1 83 84 # Build the resulting arDate and it's properties 85 result = ArDate() 86 result.year = year + YEAR_OFFSET 87 result.monthNum = month 88 result.day = day 89 result.month = arMonths[month] 90 result.monthShort = arShortMonths[month] 91 result.weekday = arDays[day_of_week] 92 result.weekdayNum = day_of_week 93 result.weekdayShort = arDayShort[day_of_week] 94 result.commonMonth = arCommonMonths[month] 95 result.season = arMonthSeasons[month] 96 97 return result 98 99 except KeyError as e: 100 raise ArConverterError(f'Invalid calendar mapping: {e}') 101 except Exception as e: 102 raise ArConverterError(f'Conversion error: {e}')
Base exception for arconverter errors.
36def validate_date(date: datetime) -> None: 37 """Validate the input date is within acceptable ranges.""" 38 if not isinstance(date, datetime): 39 raise ArConverterError('Input must be a datetime object') 40 41 if date.year < MIN_YEAR or date.year > MAX_YEAR: 42 raise ArConverterError(f'Year must be between {MIN_YEAR} and {MAX_YEAR}')
Validate the input date is within acceptable ranges.
45def convert(target_date: datetime) -> ArDate: 46 """Convert a datetime object to an Absalom Reckoning date. 47 48 Args: 49 target_date: A datetime object representing the Gregorian calendar date to convert 50 51 Returns: 52 ArDate: An Absalom Reckoning date object with the following attributes: 53 - year: AR year (Gregorian + 2700) 54 - month: Full month name 55 - monthShort: 3-letter month abbreviation 56 - commonMonth: Common folk month name 57 - day: Day of month 58 - weekday: Full weekday name 59 - weekdayShort: 3-letter weekday abbreviation 60 - weekdayNum: Day of week (1-7, Moonday=1) 61 - monthNum: Month number (1-12) 62 - season: Current season name 63 64 Raises: 65 ArConverterError: If input is not a datetime object or year is out of valid range 66 67 Examples: 68 >>> from datetime import datetime 69 >>> date = datetime(2023, 7, 10) 70 >>> ar_date = convert(date) 71 >>> print(ar_date.long_date()) 72 'Erastus 10, 4723' 73 >>> print(ar_date.season) 74 'Summer' 75 """ 76 validate_date(target_date) 77 78 try: 79 # Break the year up into pieces 80 year = target_date.year 81 month = target_date.month 82 day = target_date.day 83 day_of_week = target_date.weekday() + 1 84 85 # Build the resulting arDate and it's properties 86 result = ArDate() 87 result.year = year + YEAR_OFFSET 88 result.monthNum = month 89 result.day = day 90 result.month = arMonths[month] 91 result.monthShort = arShortMonths[month] 92 result.weekday = arDays[day_of_week] 93 result.weekdayNum = day_of_week 94 result.weekdayShort = arDayShort[day_of_week] 95 result.commonMonth = arCommonMonths[month] 96 result.season = arMonthSeasons[month] 97 98 return result 99 100 except KeyError as e: 101 raise ArConverterError(f'Invalid calendar mapping: {e}') 102 except Exception as e: 103 raise ArConverterError(f'Conversion error: {e}')
Convert a datetime object to an Absalom Reckoning date.
Args: target_date: A datetime object representing the Gregorian calendar date to convert
Returns: ArDate: An Absalom Reckoning date object with the following attributes: - year: AR year (Gregorian + 2700) - month: Full month name - monthShort: 3-letter month abbreviation - commonMonth: Common folk month name - day: Day of month - weekday: Full weekday name - weekdayShort: 3-letter weekday abbreviation - weekdayNum: Day of week (1-7, Moonday=1) - monthNum: Month number (1-12) - season: Current season name
Raises: ArConverterError: If input is not a datetime object or year is out of valid range
Examples:
from datetime import datetime date = datetime(2023, 7, 10) ar_date = convert(date) print(ar_date.long_date()) 'Erastus 10, 4723' print(ar_date.season) 'Summer'