4848from functools import cache
4949from typing import Dict , Type
5050
51+ from undate .date import Date
52+
5153logger = logging .getLogger (__name__ )
5254
5355
@@ -58,6 +60,10 @@ class BaseDateConverter:
5860 #: Converter name. Subclasses must define a unique name.
5961 name : str = "Base Converter"
6062
63+ # provisional...
64+ LEAP_YEAR = 0
65+ NON_LEAP_YEAR = 0
66+
6167 def parse (self , value : str ):
6268 """
6369 Parse a string and return an :class:`~undate.undate.Undate` or
@@ -142,6 +148,16 @@ class BaseCalendarConverter(BaseDateConverter):
142148 #: Converter name. Subclasses must define a unique name.
143149 name : str = "Base Calendar Converter"
144150
151+ #: arbitrary known non-leap year
152+ NON_LEAP_YEAR : int
153+ #: arbitrary known leap year
154+ LEAP_YEAR : int
155+
156+ # minimum year for this calendar, if there is one
157+ MIN_YEAR : None | int = None
158+ # maximum year for this calendar, if there is one
159+ MAX_YEAR : None | int = None
160+
145161 def min_month (self ) -> int :
146162 """Smallest numeric month for this calendar."""
147163 raise NotImplementedError
@@ -162,6 +178,27 @@ def max_day(self, year: int, month: int) -> int:
162178 """maximum numeric day for the specified year and month in this calendar"""
163179 raise NotImplementedError
164180
181+ def days_in_year (self , year : int ) -> int :
182+ """Number of days in the specified year in this calendar. The default implementation
183+ uses min and max month and max day methods along with Gregorian conversion method
184+ to calculate the number of days in the specified year.
185+ """
186+ year_start = Date (* self .to_gregorian (year , self .min_month (), 1 ))
187+ last_month = self .max_month (year )
188+ year_end = Date (
189+ * self .to_gregorian (year , last_month , self .max_day (year , last_month ))
190+ )
191+ # add 1 because the difference doesn't include the end point
192+ return (year_end - year_start ).days + 1
193+
194+ def representative_years (self , years : None | list [int ] = None ) -> list [int ]:
195+ """Returns a list of representative years within the specified list.
196+ Result should include one for each type of variant year for this
197+ calendar (e.g., leap year and non-leap year). If no years are specified,
198+ returns a list of representative years for the current calendar.
199+ """
200+ raise NotImplementedError
201+
165202 def to_gregorian (self , year , month , day ) -> tuple [int , int , int ]:
166203 """Convert a date for this calendar specified by numeric year, month, and day,
167204 into the Gregorian equivalent date. Should return a tuple of year, month, day.
0 commit comments