Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/tools/times.py: 8%

76 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from __future__ import annotations 

2 

3from datetime import ( 

4 datetime, 

5 time, 

6) 

7 

8import numpy as np 

9 

10from pandas._libs.lib import is_list_like 

11 

12from pandas.core.dtypes.generic import ( 

13 ABCIndex, 

14 ABCSeries, 

15) 

16from pandas.core.dtypes.missing import notna 

17 

18 

19def to_time(arg, format=None, infer_time_format=False, errors="raise"): 

20 """ 

21 Parse time strings to time objects using fixed strptime formats ("%H:%M", 

22 "%H%M", "%I:%M%p", "%I%M%p", "%H:%M:%S", "%H%M%S", "%I:%M:%S%p", 

23 "%I%M%S%p") 

24 

25 Use infer_time_format if all the strings are in the same format to speed 

26 up conversion. 

27 

28 Parameters 

29 ---------- 

30 arg : string in time format, datetime.time, list, tuple, 1-d array, Series 

31 format : str, default None 

32 Format used to convert arg into a time object. If None, fixed formats 

33 are used. 

34 infer_time_format: bool, default False 

35 Infer the time format based on the first non-NaN element. If all 

36 strings are in the same format, this will speed up conversion. 

37 errors : {'ignore', 'raise', 'coerce'}, default 'raise' 

38 - If 'raise', then invalid parsing will raise an exception 

39 - If 'coerce', then invalid parsing will be set as None 

40 - If 'ignore', then invalid parsing will return the input 

41 

42 Returns 

43 ------- 

44 datetime.time 

45 """ 

46 

47 def _convert_listlike(arg, format): 

48 

49 if isinstance(arg, (list, tuple)): 

50 arg = np.array(arg, dtype="O") 

51 

52 elif getattr(arg, "ndim", 1) > 1: 

53 raise TypeError( 

54 "arg must be a string, datetime, list, tuple, 1-d array, or Series" 

55 ) 

56 

57 arg = np.asarray(arg, dtype="O") 

58 

59 if infer_time_format and format is None: 

60 format = _guess_time_format_for_array(arg) 

61 

62 times: list[time | None] = [] 

63 if format is not None: 

64 for element in arg: 

65 try: 

66 times.append(datetime.strptime(element, format).time()) 

67 except (ValueError, TypeError) as err: 

68 if errors == "raise": 

69 msg = ( 

70 f"Cannot convert {element} to a time with given " 

71 f"format {format}" 

72 ) 

73 raise ValueError(msg) from err 

74 elif errors == "ignore": 

75 return arg 

76 else: 

77 times.append(None) 

78 else: 

79 formats = _time_formats[:] 

80 format_found = False 

81 for element in arg: 

82 time_object = None 

83 try: 

84 time_object = time.fromisoformat(element) 

85 except (ValueError, TypeError): 

86 for time_format in formats: 

87 try: 

88 time_object = datetime.strptime(element, time_format).time() 

89 if not format_found: 

90 # Put the found format in front 

91 fmt = formats.pop(formats.index(time_format)) 

92 formats.insert(0, fmt) 

93 format_found = True 

94 break 

95 except (ValueError, TypeError): 

96 continue 

97 

98 if time_object is not None: 

99 times.append(time_object) 

100 elif errors == "raise": 

101 raise ValueError(f"Cannot convert arg {arg} to a time") 

102 elif errors == "ignore": 

103 return arg 

104 else: 

105 times.append(None) 

106 

107 return times 

108 

109 if arg is None: 

110 return arg 

111 elif isinstance(arg, time): 

112 return arg 

113 elif isinstance(arg, ABCSeries): 

114 values = _convert_listlike(arg._values, format) 

115 return arg._constructor(values, index=arg.index, name=arg.name) 

116 elif isinstance(arg, ABCIndex): 

117 return _convert_listlike(arg, format) 

118 elif is_list_like(arg): 

119 return _convert_listlike(arg, format) 

120 

121 return _convert_listlike(np.array([arg]), format)[0] 

122 

123 

124# Fixed time formats for time parsing 

125_time_formats = [ 

126 "%H:%M", 

127 "%H%M", 

128 "%I:%M%p", 

129 "%I%M%p", 

130 "%H:%M:%S", 

131 "%H%M%S", 

132 "%I:%M:%S%p", 

133 "%I%M%S%p", 

134] 

135 

136 

137def _guess_time_format_for_array(arr): 

138 # Try to guess the format based on the first non-NaN element 

139 non_nan_elements = notna(arr).nonzero()[0] 

140 if len(non_nan_elements): 

141 element = arr[non_nan_elements[0]] 

142 for time_format in _time_formats: 

143 try: 

144 datetime.strptime(element, time_format) 

145 return time_format 

146 except ValueError: 

147 pass 

148 

149 return None