Coverage for kwai/core/domain/value_objects/local_timestamp.py: 82%

67 statements  

« prev     ^ index     » next       coverage.py v7.3.0, created at 2023-09-05 17:55 +0000

1"""Module that defines a value object for a local timestamp.""" 

2from dataclasses import dataclass 

3from datetime import date, datetime, time, timedelta 

4 

5 

6@dataclass(frozen=True) 

7class LocalTimestamp: 

8 """A value object for a timestamp. 

9 

10 The datetime should always be in UTC. 

11 """ 

12 

13 timestamp: datetime = None 

14 

15 @property 

16 def empty(self): 

17 """Return True when the timestamp is unknown.""" 

18 return self.timestamp is None 

19 

20 @property 

21 def is_past(self) -> bool: 

22 """Return True when the timestamp in the past.""" 

23 assert not self.empty, "No datetime set" 

24 

25 return self.timestamp < datetime.utcnow() 

26 

27 @property 

28 def year(self) -> int: 

29 """Return the year.""" 

30 if self.timestamp is None: 

31 raise ValueError("Empty timestamp") 

32 return self.timestamp.year 

33 

34 @property 

35 def month(self) -> int: 

36 """Return the month.""" 

37 if self.timestamp is None: 

38 raise ValueError("Empty timestamp") 

39 return self.timestamp.month 

40 

41 @property 

42 def day(self) -> int: 

43 """Return the day.""" 

44 if self.timestamp is None: 

45 raise ValueError("Empty timestamp") 

46 return self.timestamp.day 

47 

48 @property 

49 def hours(self) -> int: 

50 """Return the hours.""" 

51 if self.timestamp is None: 

52 raise ValueError("Empty timestamp") 

53 return self.timestamp.hour 

54 

55 @property 

56 def minutes(self) -> int: 

57 """Return the minutes.""" 

58 if self.timestamp is None: 

59 raise ValueError("Empty timestamp") 

60 return self.timestamp.minute 

61 

62 @property 

63 def seconds(self) -> int: 

64 """Return the seconds.""" 

65 if self.timestamp is None: 

66 raise ValueError("Empty timestamp") 

67 return self.timestamp.second 

68 

69 @property 

70 def date(self) -> date: 

71 """Return the date.""" 

72 if self.timestamp is None: 

73 raise ValueError("Empty timestamp") 

74 return self.timestamp.date() 

75 

76 @property 

77 def time(self) -> time: 

78 """Return the date.""" 

79 if self.timestamp is None: 

80 raise ValueError("Empty timestamp") 

81 return self.timestamp.time() 

82 

83 def __str__(self) -> str: 

84 """Return a string representation. 

85 

86 Returns: 

87 A formatted timestamp in format YYYY-MM-DD HH:mm:ss. 

88 An empty string will be returned, when no timestamp is available. 

89 """ 

90 if self.empty: 

91 return "" 

92 

93 return self.timestamp.strftime("%Y-%m-%d %H:%M:%S") 

94 

95 def add_delta(self, **kwargs) -> "LocalTimestamp": 

96 """Create a new timestamp by adding the delta to the timestamp. 

97 

98 Returns: 

99 LocalTimestamp: A new timestamp with the delta. 

100 """ 

101 return LocalTimestamp(self.timestamp + timedelta(**kwargs)) 

102 

103 @classmethod 

104 def create_with_delta(cls, **kwargs): 

105 """Create a current local timestamp and applies the delta.""" 

106 return cls.create_now().add_delta(**kwargs) 

107 

108 @classmethod 

109 def create_now(cls): 

110 """Create a timestamp with the current UTC time.""" 

111 return LocalTimestamp(timestamp=datetime.utcnow()) 

112 

113 @classmethod 

114 def create_from_string( 

115 cls, date_time: str, date_format: str = "%Y-%m-%d %H:%M:%S" 

116 ) -> "LocalTimestamp": 

117 """Create a timestamp from a string. 

118 

119 Args: 

120 date_time: The string to convert to a timestamp. 

121 date_format: The format used in the string. 

122 """ 

123 return LocalTimestamp(datetime.strptime(date_time, date_format))