Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/pandas/core/tools/times.py: 16%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

83 statements  

1from __future__ import annotations 

2 

3from datetime import ( 

4 datetime, 

5 time, 

6) 

7from typing import TYPE_CHECKING 

8import warnings 

9 

10import numpy as np 

11 

12from pandas._libs.lib import is_list_like 

13from pandas.util._exceptions import find_stack_level 

14 

15from pandas.core.dtypes.generic import ( 

16 ABCIndex, 

17 ABCSeries, 

18) 

19from pandas.core.dtypes.missing import notna 

20 

21if TYPE_CHECKING: 

22 from pandas._typing import DateTimeErrorChoices 

23 

24 

25def to_time( 

26 arg, 

27 format: str | None = None, 

28 infer_time_format: bool = False, 

29 errors: DateTimeErrorChoices = "raise", 

30): 

31 """ 

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

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

34 "%I%M%S%p") 

35 

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

37 up conversion. 

38 

39 Parameters 

40 ---------- 

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

42 format : str, default None 

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

44 are used. 

45 infer_time_format: bool, default False 

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

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

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

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

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

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

52 

53 Returns 

54 ------- 

55 datetime.time 

56 """ 

57 if errors == "ignore": 

58 # GH#54467 

59 warnings.warn( 

60 "errors='ignore' is deprecated and will raise in a future version. " 

61 "Use to_time without passing `errors` and catch exceptions " 

62 "explicitly instead", 

63 FutureWarning, 

64 stacklevel=find_stack_level(), 

65 ) 

66 

67 def _convert_listlike(arg, format): 

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

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

70 

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

72 raise TypeError( 

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

74 ) 

75 

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

77 

78 if infer_time_format and format is None: 

79 format = _guess_time_format_for_array(arg) 

80 

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

82 if format is not None: 

83 for element in arg: 

84 try: 

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

86 except (ValueError, TypeError) as err: 

87 if errors == "raise": 

88 msg = ( 

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

90 f"format {format}" 

91 ) 

92 raise ValueError(msg) from err 

93 if errors == "ignore": 

94 return arg 

95 else: 

96 times.append(None) 

97 else: 

98 formats = _time_formats[:] 

99 format_found = False 

100 for element in arg: 

101 time_object = None 

102 try: 

103 time_object = time.fromisoformat(element) 

104 except (ValueError, TypeError): 

105 for time_format in formats: 

106 try: 

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

108 if not format_found: 

109 # Put the found format in front 

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

111 formats.insert(0, fmt) 

112 format_found = True 

113 break 

114 except (ValueError, TypeError): 

115 continue 

116 

117 if time_object is not None: 

118 times.append(time_object) 

119 elif errors == "raise": 

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

121 elif errors == "ignore": 

122 return arg 

123 else: 

124 times.append(None) 

125 

126 return times 

127 

128 if arg is None: 

129 return arg 

130 elif isinstance(arg, time): 

131 return arg 

132 elif isinstance(arg, ABCSeries): 

133 values = _convert_listlike(arg._values, format) 

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

135 elif isinstance(arg, ABCIndex): 

136 return _convert_listlike(arg, format) 

137 elif is_list_like(arg): 

138 return _convert_listlike(arg, format) 

139 

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

141 

142 

143# Fixed time formats for time parsing 

144_time_formats = [ 

145 "%H:%M", 

146 "%H%M", 

147 "%I:%M%p", 

148 "%I%M%p", 

149 "%H:%M:%S", 

150 "%H%M%S", 

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

152 "%I%M%S%p", 

153] 

154 

155 

156def _guess_time_format_for_array(arr): 

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

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

159 if len(non_nan_elements): 

160 element = arr[non_nan_elements[0]] 

161 for time_format in _time_formats: 

162 try: 

163 datetime.strptime(element, time_format) 

164 return time_format 

165 except ValueError: 

166 pass 

167 

168 return None