Coverage for src/kwai/core/domain/value_objects/time_period.py: 91%
22 statements
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
1"""Module that defines a period between times."""
3from dataclasses import dataclass
4from datetime import date, datetime, time, timedelta
7@dataclass(frozen=True, kw_only=True, slots=True)
8class TimePeriod:
9 """A period between two times."""
11 start: time
12 end: time | None = None
13 timezone: str = "UTC"
15 def __post_init__(self):
16 """Perform post initialization.
18 Raises:
19 ValueError: when the start time is before the end time.
20 """
21 if self.end is not None:
22 if self.start > self.end:
23 raise ValueError("start should be before end")
25 @property
26 def endless(self) -> bool:
27 """Return True when the period does not have an end time."""
28 return self.end is None
30 @property
31 def delta(self) -> timedelta | None:
32 """Return the delta between end and start time.
34 Returns: The delta between the start and end time.
36 When there is no end time, the result will be None.
37 """
38 if self.end is None:
39 return None
41 return datetime.combine(date(1, 1, 1), self.end) - datetime.combine(
42 date(1, 1, 1), self.start
43 )
45 @classmethod
46 def create_from_string(
47 cls, start: str, end: str | None = None, timezone: str = "UTC"
48 ) -> "TimePeriod":
49 """Create a time period from one or two strings.
51 Args:
52 start: a start time in format 00:00
53 end: an optional end time in format 00:00
54 timezone: an optional timezone name
56 Returns:
57 A new time period.
58 """
59 return TimePeriod(
60 start=datetime.strptime(start, "%H:%M").time(),
61 end=None if end is None else datetime.strptime(end, "%H:%M").time(),
62 timezone=timezone,
63 )