From d9a9b13f4329aef8f027eadd061f2c475861825a Mon Sep 17 00:00:00 2001 From: kinegratii Date: Mon, 12 Feb 2024 20:03:29 +0800 Subject: [PATCH] :sparkles: add freq string for SolarFestival&LunarFestival --- borax/calendars/festivals2.py | 17 ++++++++++++++--- docs/changelog.md | 4 ++++ docs/guides/festivals2.md | 28 +++++++++++++++++----------- tests/test_festival2_list.py | 13 +++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/borax/calendars/festivals2.py b/borax/calendars/festivals2.py index e402ab5..49f0ccd 100644 --- a/borax/calendars/festivals2.py +++ b/borax/calendars/festivals2.py @@ -30,6 +30,8 @@ class FreqConst: YEARLY = 0 MONTHLY = 1 + LABEL2VAL = {'monthly': 1, 'yearly': 0, 'm': 1, 'y': 0} + class FestivalCatalog: basic = 'basic' @@ -460,12 +462,17 @@ class SolarFestival(Festival): """ date_class = date - def __init__(self, *, day: int, freq: int = FreqConst.YEARLY, month: int = 0, name: str = None): + def __init__(self, *, day: int, freq: Union[int, Literal['yearly', 'monthly', 'y', 'm']] = FreqConst.YEARLY, + month: int = 0, name: str = None): if day < 0: day = -day reverse = 1 else: reverse = 0 + if isinstance(freq, str): + freq = FreqConst.LABEL2VAL.get(freq, -1) + if freq == -1: + raise ValueError('Invalid freq string.') super().__init__(name=name, freq=freq, month=month, day=day, reverse=reverse, schema=FestivalSchema.SOLAR) def _get_description(self) -> str: @@ -680,13 +687,17 @@ class LunarFestival(Festival): """ date_class = LunarDate - def __init__(self, *, day: int, freq: int = FreqConst.YEARLY, month: int = 0, leap: int = _IGNORE_LEAP_MONTH, - name: str = None): + def __init__(self, *, day: int, freq: Union[int, Literal['yearly', 'monthly', 'y', 'm']] = FreqConst.YEARLY, + month: int = 0, leap: int = _IGNORE_LEAP_MONTH, name: str = None): if day < 0: day = -day reverse = 1 else: reverse = 0 + if isinstance(freq, str): + freq = FreqConst.LABEL2VAL.get(freq, -1) + if freq == -1: + raise ValueError('Invalid freq string.') super().__init__(freq=freq, name=name, month=month, day=day, leap=leap, reverse=reverse, schema=FestivalSchema.LUNAR) diff --git a/docs/changelog.md b/docs/changelog.md index 9c4aa6d..0de0594 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,9 @@ # 更新日志 +## v4.1.1 + +- `SolarFestival` 和`LunarFestival` 初始化函数 `freq` 参数支持字符串设置( [ #56](https://github.com/kinegratii/borax/issues/56) ) + ## v4.1.0 (20240131) > Borax最低python版本要求为python3.9 diff --git a/docs/guides/festivals2.md b/docs/guides/festivals2.md index 0d5aa2c..a6fedac 100644 --- a/docs/guides/festivals2.md +++ b/docs/guides/festivals2.md @@ -2,6 +2,8 @@ > 模块: `borax.calendars.festivals2` +> Updated in 4.1.1: SolarFestival和LunarFestival的freq参数支持字符串形式。 + > Updated in 4.1.0:新增 Festival.code属性。 > Updated in 3.5.6: 星期型节日(WeekFestival)类支持倒数序号。如:“国际麻风节(1月最后一个星期天)” @@ -161,11 +163,13 @@ class SolarFestival(*, day: int, freq: int = FreqConst.YEARLY, month: int = 0, n 参数定义 -| 参数 | 描述 | 取值 | -| ----- | ------------------------------------------------------------ | -------------- | -| freq | 节日频率,“每年”或“每月”,默认“每年”。 | 0:每年;1:每月 | -| month | 月份。 | 0,1-12 | -| day | 日期序号。当month取值0时,表示一年的第几天;否则表示该月的第几天。允许取负值,表示一年/一个月的倒数 第几天。 | | +| 参数 | 描述 | 取值 | +| ----- | ------------------------------------------------------------ | ---------------------------------------------- | +| freq | 节日频率,“每年”或“每月”,默认“每年”。 | 0/yearly/y:每年;1/monthly/m:每月 1 | +| month | 月份。 | 0,1-12 | +| day | 日期序号。当month取值0时,表示一年的第几天;否则表示该月的第几天。允许取负值,表示一年/一个月的倒数 第几天。 | | + +1. v4.1.1 新增字符串形式。 6种形式定义 @@ -186,12 +190,14 @@ class LunarFestival(*, day:int, freq:int=FreqConst.YEARLY, month:int=0, leap:int 参数定义 -| 参数 | 描述 | 取值 | -| ----- | ------------------------------------------------------------ | --------------- | -| freq | 节日频率,“每年”或“每月”,默认“每年”。 | 0:每年;1:每月 | -| month | 月份。 | 0,1-12 | -| leap | 闰月标记。取值参见 `LeapConst`。 | LeapConst.MIXED | -| day | 日期序号。当month未设置时,表示一年的第几天;否则表示该月的第几天。允许取负值,表示一年/一个月的倒数 第几天。 | | +| 参数 | 描述 | 取值 | +| ----- | ------------------------------------------------------------ | ---------------------------------------------- | +| freq | 节日频率,“每年”或“每月”,默认“每年”。 | 0/yearly/y:每年;1/monthly/m:每月 1 | +| month | 月份。 | 0,1-12 | +| leap | 闰月标记。取值参见 `LeapConst`。 | LeapConst.MIXED | +| day | 日期序号。当month未设置时,表示一年的第几天;否则表示该月的第几天。允许取负值,表示一年/一个月的倒数 第几天。 | | + +1. v4.1.1 新增字符串形式。 ### WeekFestival diff --git a/tests/test_festival2_list.py b/tests/test_festival2_list.py index 421ec86..463881c 100644 --- a/tests/test_festival2_list.py +++ b/tests/test_festival2_list.py @@ -47,6 +47,13 @@ def test_reverse(self): self.assertEqual(date(2021, 2, 28), sf2.at(year=2021, month=2)) self.assertEqual(date(2020, 2, 29), sf2.at(year=2020, month=2)) + def test_freq_string(self): + sf = SolarFestival(freq='monthly', day=1) + self.assertTrue(sf.is_(date(2024, 2, 1))) + + with self.assertRaises(ValueError): + sf2 = SolarFestival(freq='33', day=1) + class WeekFestivalTestCase(unittest.TestCase): def test_basic_logic(self): @@ -136,6 +143,12 @@ def test_monthly(self): with self.assertRaises(FestivalError): lf.at(year=2021) + def test_freq_string(self): + lf = LunarFestival(freq='m', day=1) + self.assertTrue(lf.is_(LunarDate(2024, 1, 1))) + with self.assertRaises(ValueError): + LunarFestival(freq='xxx', day=1) + class CheckFestivalTestCase(unittest.TestCase): def test_all_days(self):