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

1"""FirstAndLastDateOfPeriod class 

2 

3Helper class for figuring out dates relative to a given date 

4""" 

5from datetime import date, timedelta 

6from dateutil.relativedelta import relativedelta 

7 

8 

9class FirstAndLastDateOfPeriod: 

10 """Encapsulate all the logic to determine first and last date 

11 of a period that includes the supplied date 

12 """ 

13 

14 def __init__(self, date_in_period: date) -> None: 

15 self.__date_in_period = date_in_period 

16 

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 ) 

24 

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 ) 

30 

31 @property 

32 def first_date_in_month(self) -> date: 

33 return date(self.__date_in_period.year, self.__date_in_period.month, 1) 

34 

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 ) 

42 

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 ) 

54 

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 ) 

66 

67 @property 

68 def first_date_in_year(self) -> date: 

69 return date(self.__date_in_period.year, 1, 1) 

70 

71 @property 

72 def last_date_in_year(self) -> date: 

73 return date(self.__date_in_period.year, 12, 31)