Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pandas/core/tools/times.py: 13%

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

77 statements  

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 

11from pandas._typing import DateTimeErrorChoices 

12 

13from pandas.core.dtypes.generic import ( 

14 ABCIndex, 

15 ABCSeries, 

16) 

17from pandas.core.dtypes.missing import notna 

18 

19 

20def to_time( 

21 arg, 

22 format=None, 

23 infer_time_format: bool = False, 

24 errors: DateTimeErrorChoices = "raise", 

25): 

26 """ 

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

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

29 "%I%M%S%p") 

30 

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

32 up conversion. 

33 

34 Parameters 

35 ---------- 

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

37 format : str, default None 

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

39 are used. 

40 infer_time_format: bool, default False 

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

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

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

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

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

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

47 

48 Returns 

49 ------- 

50 datetime.time 

51 """ 

52 

53 def _convert_listlike(arg, format): 

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

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

56 

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

58 raise TypeError( 

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

60 ) 

61 

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

63 

64 if infer_time_format and format is None: 

65 format = _guess_time_format_for_array(arg) 

66 

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

68 if format is not None: 

69 for element in arg: 

70 try: 

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

72 except (ValueError, TypeError) as err: 

73 if errors == "raise": 

74 msg = ( 

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

76 f"format {format}" 

77 ) 

78 raise ValueError(msg) from err 

79 if errors == "ignore": 

80 return arg 

81 else: 

82 times.append(None) 

83 else: 

84 formats = _time_formats[:] 

85 format_found = False 

86 for element in arg: 

87 time_object = None 

88 try: 

89 time_object = time.fromisoformat(element) 

90 except (ValueError, TypeError): 

91 for time_format in formats: 

92 try: 

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

94 if not format_found: 

95 # Put the found format in front 

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

97 formats.insert(0, fmt) 

98 format_found = True 

99 break 

100 except (ValueError, TypeError): 

101 continue 

102 

103 if time_object is not None: 

104 times.append(time_object) 

105 elif errors == "raise": 

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

107 elif errors == "ignore": 

108 return arg 

109 else: 

110 times.append(None) 

111 

112 return times 

113 

114 if arg is None: 

115 return arg 

116 elif isinstance(arg, time): 

117 return arg 

118 elif isinstance(arg, ABCSeries): 

119 values = _convert_listlike(arg._values, format) 

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

121 elif isinstance(arg, ABCIndex): 

122 return _convert_listlike(arg, format) 

123 elif is_list_like(arg): 

124 return _convert_listlike(arg, format) 

125 

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

127 

128 

129# Fixed time formats for time parsing 

130_time_formats = [ 

131 "%H:%M", 

132 "%H%M", 

133 "%I:%M%p", 

134 "%I%M%p", 

135 "%H:%M:%S", 

136 "%H%M%S", 

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

138 "%I%M%S%p", 

139] 

140 

141 

142def _guess_time_format_for_array(arr): 

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

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

145 if len(non_nan_elements): 

146 element = arr[non_nan_elements[0]] 

147 for time_format in _time_formats: 

148 try: 

149 datetime.strptime(element, time_format) 

150 return time_format 

151 except ValueError: 

152 pass 

153 

154 return None