Coverage for src/kwai/core/domain/value_objects/date.py: 95%

39 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2024-01-01 00:00 +0000

1"""Module for defining a date value object.""" 

2 

3import datetime 

4 

5from dataclasses import dataclass 

6from typing import Self 

7 

8import pendulum 

9 

10 

11@dataclass(kw_only=True, frozen=True, slots=True) 

12class Date: 

13 """An immutable value object for a date. 

14 

15 This class is a decorator of a pendulum object. 

16 See: https://pendulum.eustace.io 

17 """ 

18 

19 date: pendulum 

20 

21 def add(self, **kwargs) -> Self: 

22 """Add time.""" 

23 return Date(date=self.date.add(**kwargs)) 

24 

25 @property 

26 def day(self) -> int: 

27 """Return the day of the date.""" 

28 return self.date.day 

29 

30 def end_of(self, unit: str) -> Self: 

31 """Returns a new date resetting it to the end of the given unit.""" 

32 return Date(date=self.date.end_of(unit)) 

33 

34 def get_age(self, some_date: Self): 

35 """Return the age on the given date.""" 

36 return ( 

37 some_date.year 

38 - self.date.year 

39 - ((some_date.month, some_date.day) < (self.date.month, self.date.day)) 

40 ) 

41 

42 @property 

43 def past(self) -> bool: 

44 """Is this date in the past?""" 

45 return self.date < pendulum.now() 

46 

47 @property 

48 def month(self) -> int: 

49 """Return the month of the date.""" 

50 return self.date.month 

51 

52 @property 

53 def year(self) -> int: 

54 """Return the year of the date.""" 

55 return self.date.year 

56 

57 @classmethod 

58 def today(cls) -> Self: 

59 """Return today as date.""" 

60 return Date(date=pendulum.today()) 

61 

62 @classmethod 

63 def create_from_string(cls, value: str, format_: str = "YYYY-MM-DD") -> Self: 

64 """Create a Date from a string.""" 

65 return Date(date=pendulum.from_format(value, format_).date()) 

66 

67 @classmethod 

68 def create_from_date(cls, date: datetime.date) -> Self: 

69 """Create a Date from a datetime.date.""" 

70 return cls.create(date.year, date.month, date.day) 

71 

72 @classmethod 

73 def create(cls, year: int, month: int = 1, day: int = 1): 

74 """Create a date with the given year, month and day.""" 

75 return Date(date=pendulum.date(year, month, day)) 

76 

77 def __str__(self) -> str: 

78 """Return a string representation of the date.""" 

79 return self.date.to_date_string()