Coverage for jstark/features/first_and_last_date_of_period.py: 100%
29 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-02-25 20:09 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-02-25 20:09 +0000
1"""FirstAndLastDateOfPeriod class
3Helper class for figuring out dates relative to a given date
4"""
5from datetime import date, timedelta
6from dateutil.relativedelta import relativedelta
9class FirstAndLastDateOfPeriod:
10 """Encapsulate all the logic to determine first and last date
11 of a period that includes the supplied date
12 """
14 def __init__(self, date_in_period: date) -> None:
15 self.__date_in_period = date_in_period
17 @property
18 def first_date_in_week(self) -> date:
19 # Use strftime because we want Sunday to be first day of the week.
20 # date.DayOfWeek() has different behaviour
21 return self.__date_in_period - timedelta(
22 days=int(self.__date_in_period.strftime("%w"))
23 )
25 @property
26 def last_date_in_week(self) -> date:
27 return self.__date_in_period + timedelta(
28 days=6 - int(self.__date_in_period.strftime("%w"))
29 )
31 @property
32 def first_date_in_month(self) -> date:
33 return date(self.__date_in_period.year, self.__date_in_period.month, 1)
35 @property
36 def last_date_in_month(self) -> date:
37 return (
38 self.__date_in_period
39 + relativedelta(months=1, day=1)
40 - relativedelta(days=1)
41 )
43 @property
44 def first_date_in_quarter(self) -> date:
45 return (
46 date(self.__date_in_period.year, 1, 1)
47 if self.__date_in_period.month in [1, 2, 3]
48 else date(self.__date_in_period.year, 4, 1)
49 if self.__date_in_period.month in [4, 5, 6]
50 else date(self.__date_in_period.year, 7, 1)
51 if self.__date_in_period.month in [7, 8, 9]
52 else date(self.__date_in_period.year, 10, 1)
53 )
55 @property
56 def last_date_in_quarter(self) -> date:
57 return (
58 date(self.__date_in_period.year, 3, 31)
59 if self.__date_in_period.month in [1, 2, 3]
60 else date(self.__date_in_period.year, 6, 30)
61 if self.__date_in_period.month in [4, 5, 6]
62 else date(self.__date_in_period.year, 9, 30)
63 if self.__date_in_period.month in [7, 8, 9]
64 else date(self.__date_in_period.year, 12, 31)
65 )
67 @property
68 def first_date_in_year(self) -> date:
69 return date(self.__date_in_period.year, 1, 1)
71 @property
72 def last_date_in_year(self) -> date:
73 return date(self.__date_in_period.year, 12, 31)