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

1"""Module that defines a period between times.""" 

2 

3from dataclasses import dataclass 

4from datetime import date, datetime, time, timedelta 

5 

6 

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

8class TimePeriod: 

9 """A period between two times.""" 

10 

11 start: time 

12 end: time | None = None 

13 timezone: str = "UTC" 

14 

15 def __post_init__(self): 

16 """Perform post initialization. 

17 

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") 

24 

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 

29 

30 @property 

31 def delta(self) -> timedelta | None: 

32 """Return the delta between end and start time. 

33 

34 Returns: The delta between the start and end time. 

35 

36 When there is no end time, the result will be None. 

37 """ 

38 if self.end is None: 

39 return None 

40 

41 return datetime.combine(date(1, 1, 1), self.end) - datetime.combine( 

42 date(1, 1, 1), self.start 

43 ) 

44 

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. 

50 

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 

55 

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 )