Coverage for plugins/module_utils/time_utils.py: 98%

42 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-10-30 17:06 -0400

1# -*- coding: utf-8 -*- 

2 

3# Copyright: (c) 2024, Pure Storage Inc. 

4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 

5 

6"""Time conversion utilities for FlashBlade modules.""" 

7 

8from __future__ import absolute_import, division, print_function 

9 

10__metaclass__ = type 

11 

12from typing import Optional 

13 

14 

15class TimeConversionError(Exception): 

16 """Raised when time conversion fails.""" 

17 

18 pass 

19 

20 

21def time_to_milliseconds(time_str: str) -> int: 

22 """ 

23 Convert various time formats to milliseconds. 

24 

25 Supports: 

26 - 12-hour clock: '02AM', '2AM', '11PM', '12AM', '12PM' 

27 - Duration: '2w', '3d', '4h', '5m', '6s' 

28 

29 Args: 

30 time_str: Time string to convert 

31 

32 Returns: 

33 Milliseconds as integer 

34 

35 Raises: 

36 TimeConversionError: If format is invalid 

37 

38 Examples: 

39 >>> time_to_milliseconds('02AM') 

40 7200000 

41 >>> time_to_milliseconds('2d') 

42 172800000 

43 """ 

44 if not time_str: 

45 raise TimeConversionError("Time string cannot be empty") 

46 

47 # Try 12-hour clock format 

48 if len(time_str) >= 3 and time_str[-2:].upper() in ("AM", "PM"): 

49 return _clock_to_milliseconds(time_str) 

50 

51 # Try duration format 

52 if len(time_str) >= 2 and time_str[-1].lower() in ("w", "d", "h", "m", "s"): 

53 return _duration_to_milliseconds(time_str) 

54 

55 raise TimeConversionError(f"Invalid time format: {time_str}") 

56 

57 

58def _clock_to_milliseconds(hour_str: str) -> int: 

59 """Convert 12-hour clock to milliseconds from midnight.""" 

60 try: 

61 time_part = int(hour_str[:-2]) 

62 period = hour_str[-2:].upper() 

63 

64 if not 1 <= time_part <= 12: 

65 raise TimeConversionError(f"Hour must be 1-12, got {time_part}") 

66 

67 if period == "AM": 

68 return 0 if time_part == 12 else time_part * 3600000 

69 else: # PM 

70 return 43200000 if time_part == 12 else (time_part + 12) * 3600000 

71 

72 except (ValueError, IndexError) as e: 

73 raise TimeConversionError(f"Invalid clock format: {hour_str}") from e 

74 

75 

76def _duration_to_milliseconds(duration_str: str) -> int: 

77 """Convert duration string to milliseconds.""" 

78 multipliers = { 

79 "w": 7 * 86400000, # weeks 

80 "d": 86400000, # days 

81 "h": 3600000, # hours 

82 "m": 60000, # minutes 

83 "s": 1000, # seconds 

84 } 

85 

86 try: 

87 unit = duration_str[-1].lower() 

88 number = int(duration_str[:-1]) 

89 

90 if unit not in multipliers: 

91 raise TimeConversionError(f"Invalid time unit: {unit}") 

92 

93 if number < 0: 

94 raise TimeConversionError(f"Duration must be positive, got {number}") 

95 

96 return number * multipliers[unit] 

97 

98 except (ValueError, IndexError) as e: 

99 raise TimeConversionError(f"Invalid duration format: {duration_str}") from e 

100 

101 

102def milliseconds_to_time(millisecs: Optional[int]) -> Optional[str]: 

103 """ 

104 Convert milliseconds to HH:MM time string. 

105 

106 Args: 

107 millisecs: Milliseconds from midnight 

108 

109 Returns: 

110 Time string in HH:MM format, or None if input is None/0 

111 

112 Examples: 

113 >>> milliseconds_to_time(7200000) 

114 '02:00' 

115 >>> milliseconds_to_time(43200000) 

116 '12:00' 

117 """ 

118 if not millisecs: 

119 return None 

120 

121 hours = int(millisecs / 3600000) % 24 

122 minutes = int((millisecs % 3600000) / 60000) 

123 return f"{hours:02d}:{minutes:02d}"