Coverage for nexusLIMS/utils/time.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2026-03-24 05:23 +0000

1"""Time and date utilities for NexusLIMS.""" 

2 

3import time 

4from datetime import datetime, timedelta 

5from typing import Tuple 

6 

7import pytz 

8import tzlocal 

9 

10from nexusLIMS.config import settings 

11 

12# Re-export time.sleep for backward compatibility with tests 

13sleep = time.sleep 

14 

15 

16def get_timespan_overlap( 

17 range_1: Tuple[datetime, datetime], 

18 range_2: Tuple[datetime, datetime], 

19) -> timedelta: 

20 """ 

21 Find the amount of overlap between two time spans. 

22 

23 Adapted from https://stackoverflow.com/a/9044111. 

24 

25 Parameters 

26 ---------- 

27 range_1 

28 Tuple of length 2 of datetime objects: first is the start of the time 

29 range and the second is the end of the time range 

30 range_2 

31 Tuple of length 2 of datetime objects: first is the start of the time 

32 range and the second is the end of the time range 

33 

34 Returns 

35 ------- 

36 datetime.timedelta 

37 The amount of overlap between the time ranges 

38 """ 

39 latest_start = max(range_1[0], range_2[0]) 

40 earliest_end = min(range_1[1], range_2[1]) 

41 delta = earliest_end - latest_start 

42 

43 return max(timedelta(0), delta) 

44 

45 

46def has_delay_passed(date: datetime) -> bool: 

47 """ 

48 Check if the current time is greater than the configured delay. 

49 

50 Check if the current time is greater than the configured (or default) record 

51 building delay configured in the ``NX_FILE_DELAY_DAYS`` environment variable. 

52 If the date given is timezone-aware, the current time in that timezone will be 

53 compared. 

54 

55 Parameters 

56 ---------- 

57 date 

58 The datetime to check; can be either timezone aware or naive 

59 

60 Returns 

61 ------- 

62 bool 

63 Whether the current time is greater than the given date plus the 

64 configurable delay. 

65 """ 

66 # get record builder delay from settings (already validated as float > 0) 

67 delay = timedelta(days=settings.NX_FILE_DELAY_DAYS) 

68 

69 # Match timezone awareness of input date 

70 now = ( 

71 datetime.now() # noqa: DTZ005 

72 if date.tzinfo is None 

73 else datetime.now(date.tzinfo) 

74 ) 

75 

76 delta = now - date 

77 

78 return delta > delay 

79 

80 

81def current_system_tz_name() -> str: 

82 """ 

83 Get the system's timezone name. 

84 

85 Returns the IANA timezone database name for the system's current timezone 

86 (e.g., 'America/New_York'), never a simple UTC offset. 

87 

88 Returns 

89 ------- 

90 str 

91 The IANA timezone name (e.g., 'America/New_York', 'Europe/London') 

92 

93 Examples 

94 -------- 

95 >>> current_system_tz_name() 

96 'America/New_York' 

97 """ 

98 # Get the system's local timezone using tzlocal 

99 return tzlocal.get_localzone_name() 

100 

101 

102def current_system_tz() -> pytz.tzinfo.DstTzInfo: 

103 """ 

104 Get the system's timezone as a pytz timezone object. 

105 

106 Returns the system's current timezone as a pytz timezone object with a 

107 named timezone (e.g., 'America/New_York'), never a simple UTC offset. 

108 

109 Returns 

110 ------- 

111 pytz.tzinfo.DstTzInfo 

112 A pytz timezone object representing the system's timezone 

113 

114 Examples 

115 -------- 

116 >>> tz = get_system_tz() 

117 >>> tz.zone 

118 'America/New_York' 

119 """ 

120 # Return the corresponding pytz timezone object 

121 return pytz.timezone(current_system_tz_name())