From daeb20c84cfae3554d4c3f44e8bd68c0083ddc90 Mon Sep 17 00:00:00 2001 From: PyryL Date: Sun, 18 Dec 2022 20:29:35 +0200 Subject: [PATCH] initialization from fixed calendar day and month --- fixedcal/core/date.py | 18 ++++++++++++ tests/fixed_date_init_test.py | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/fixed_date_init_test.py diff --git a/fixedcal/core/date.py b/fixedcal/core/date.py index 6f3a99f..beea0fd 100644 --- a/fixedcal/core/date.py +++ b/fixedcal/core/date.py @@ -19,9 +19,13 @@ class FixedDate: def __init__(self, date: datetime.date = None, day_of_year: int = None, + day: int = None, + month: int = None, year: int = None) -> None: if isinstance(date, datetime.date): init_tuple = self._from_datetime(date) + elif isinstance(day, int) and isinstance(month, int) and isinstance(year, int): + init_tuple = self._from_fixed_date(day, month, year) elif isinstance(day_of_year, int) and isinstance(year, int): init_tuple = self._from_day_of_year(day_of_year, year) else: @@ -41,6 +45,20 @@ class FixedDate: day_of_year = date.timetuple().tm_yday return self._from_day_of_year(day_of_year, date.year) + def _from_fixed_date(self, day: int, month: int, year: int) -> tuple: + is_this_leap_year = is_leap_year(year) + + maximum_allowed_day = 29 if (is_this_leap_year and month == 6) or month == 13 else 28 + if day < 1 or day > maximum_allowed_day: + raise ValueError(f"Parameter day should be in range 1...{maximum_allowed_day}") + if month < 1 or month > 13: + raise ValueError("Parameter month should be in range 1...13") + + day_of_year = 28*(month-1) + day + if is_this_leap_year and month > 6: + day_of_year += 1 + return (day_of_year, year) + def _from_day_of_year(self, day_of_year: int, year: int) -> tuple: """Initialize this class with day of year and year. diff --git a/tests/fixed_date_init_test.py b/tests/fixed_date_init_test.py new file mode 100644 index 0000000..63f1443 --- /dev/null +++ b/tests/fixed_date_init_test.py @@ -0,0 +1,54 @@ +import unittest +import datetime +from fixedcal.core.date import FixedDate + +class TestInitWithFixedDate(unittest.TestCase): + def test_january_first(self): + fixed_date = FixedDate(day=1, month=1, year=2022) + self.assertEqual(fixed_date.date, datetime.date(2022, 1, 1)) + self.assertEqual(fixed_date.day_of_year, 1) + + def test_non_leap_year_day(self): + fixed_date = FixedDate(day=29, month=13, year=2022) + self.assertEqual(fixed_date.date, datetime.date(2022, 12, 31)) + self.assertTrue(fixed_date.is_year_day) + + def test_leap_year_day(self): + fixed_date = FixedDate(day=29, month=13, year=2024) + self.assertEqual(fixed_date.date, datetime.date(2024, 12, 31)) + self.assertTrue(fixed_date.is_year_day) + + def test_leap_year_june_last(self): + fixed_date = FixedDate(day=28, month=6, year=2024) + self.assertEqual(fixed_date.date, datetime.date(2024, 6, 16)) + self.assertFalse(fixed_date.is_leap_day) + + def test_leap_year_leap_day(self): + fixed_date = FixedDate(day=29, month=6, year=2024) + self.assertEqual(fixed_date.date, datetime.date(2024, 6, 17)) + self.assertTrue(fixed_date.is_leap_day) + + def test_leap_year_sol_first(self): + fixed_date = FixedDate(day=1, month=7, year=2024) + self.assertEqual(fixed_date.date, datetime.date(2024, 6, 18)) + self.assertFalse(fixed_date.is_leap_day) + + def test_non_leap_year_sol_first(self): + fixed_date = FixedDate(day=1, month=7, year=2022) + self.assertEqual(fixed_date.date, datetime.date(2022, 6, 18)) + self.assertFalse(fixed_date.is_leap_day) + + def test_non_leap_year_leap_day_raises(self): + self.assertRaises(ValueError, lambda : FixedDate(day=29, month=6, year=2022)) + + def test_day_too_big_raises(self): + self.assertRaises(ValueError, lambda : FixedDate(day=29, month=12, year=2022)) + + def test_day_zero_raises(self): + self.assertRaises(ValueError, lambda : FixedDate(day=0, month=3, year=2022)) + + def test_month_zero_raises(self): + self.assertRaises(ValueError, lambda : FixedDate(day=15, month=0, year=2022)) + + def test_month_too_big_raises(self): + self.assertRaises(ValueError, lambda : FixedDate(day=15, month=14, year=2022))