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
« 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
6@dataclass(frozen=True)
7class LocalTimestamp:
8 """A value object for a timestamp.
10 The datetime should always be in UTC.
11 """
13 timestamp: datetime = None
15 @property
16 def empty(self):
17 """Return True when the timestamp is unknown."""
18 return self.timestamp is None
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"
25 return self.timestamp < datetime.utcnow()
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
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
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
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
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
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
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()
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()
83 def __str__(self) -> str:
84 """Return a string representation.
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 ""
93 return self.timestamp.strftime("%Y-%m-%d %H:%M:%S")
95 def add_delta(self, **kwargs) -> "LocalTimestamp":
96 """Create a new timestamp by adding the delta to the timestamp.
98 Returns:
99 LocalTimestamp: A new timestamp with the delta.
100 """
101 return LocalTimestamp(self.timestamp + timedelta(**kwargs))
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)
108 @classmethod
109 def create_now(cls):
110 """Create a timestamp with the current UTC time."""
111 return LocalTimestamp(timestamp=datetime.utcnow())
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.
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))