Skip to content

Commit cd0ee22

Browse files
author
Lzforevr
committed
enhancement on times.py
1 parent e78ebd3 commit cd0ee22

File tree

1 file changed

+58
-66
lines changed

1 file changed

+58
-66
lines changed

pandas/core/tools/times.py

Lines changed: 58 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,48 @@
11
from __future__ import annotations
2-
3-
from datetime import (
4-
datetime,
5-
time,
6-
)
7-
from typing import TYPE_CHECKING
8-
2+
from datetime import datetime, time
3+
from typing import TYPE_CHECKING, List, Union
94
import numpy as np
10-
115
from pandas._libs.lib import is_list_like
12-
13-
from pandas.core.dtypes.generic import (
14-
ABCIndex,
15-
ABCSeries,
16-
)
6+
from pandas.core.dtypes.generic import ABCIndex, ABCSeries
177
from pandas.core.dtypes.missing import notna
188

199
if TYPE_CHECKING:
2010
from pandas._typing import DateTimeErrorChoices
2111

2212

2313
def to_time(
24-
arg,
25-
format: str | None = None,
26-
infer_time_format: bool = False,
27-
errors: DateTimeErrorChoices = "raise",
14+
arg,
15+
format: Union[str, List[str], None] = None,
16+
infer_time_format: bool = False,
17+
errors: DateTimeErrorChoices = "raise",
18+
custom_formats: List[str] = None,
2819
):
2920
"""
30-
Parse time strings to time objects using fixed strptime formats ("%H:%M",
31-
"%H%M", "%I:%M%p", "%I%M%p", "%H:%M:%S", "%H%M%S", "%I:%M:%S%p",
32-
"%I%M%S%p")
33-
34-
Use infer_time_format if all the strings are in the same format to speed
35-
up conversion.
36-
37-
Parameters
38-
----------
39-
arg : string in time format, datetime.time, list, tuple, 1-d array, Series
40-
format : str, default None
41-
Format used to convert arg into a time object. If None, fixed formats
42-
are used.
43-
infer_time_format: bool, default False
44-
Infer the time format based on the first non-NaN element. If all
45-
strings are in the same format, this will speed up conversion.
46-
errors : {'raise', 'coerce'}, default 'raise'
47-
- If 'raise', then invalid parsing will raise an exception
48-
- If 'coerce', then invalid parsing will be set as None
49-
50-
Returns
51-
-------
52-
datetime.time
53-
"""
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") and additional custom formats.
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 or list of str, default None
32+
Format(s) used to convert arg into a time object. If None, fixed
33+
formats 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 : {'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+
custom_formats : list of str, default None
41+
Additional custom time formats to use.
42+
Returns
43+
-------
44+
datetime.time or list of datetime.time
45+
"""
5446
if errors not in ("raise", "coerce"):
5547
raise ValueError("errors must be one of 'raise', or 'coerce'.")
5648

@@ -62,28 +54,37 @@ def _convert_listlike(arg, format):
6254
raise TypeError(
6355
"arg must be a string, datetime, list, tuple, 1-d array, or Series"
6456
)
65-
6657
arg = np.asarray(arg, dtype="O")
6758

6859
if infer_time_format and format is None:
6960
format = _guess_time_format_for_array(arg)
70-
71-
times: list[time | None] = []
61+
times = []
7262
if format is not None:
73-
for element in arg:
74-
try:
75-
times.append(datetime.strptime(element, format).time())
76-
except (ValueError, TypeError) as err:
77-
if errors == "raise":
78-
msg = (
79-
f"Cannot convert {element} to a time with given "
80-
f"format {format}"
81-
)
82-
raise ValueError(msg) from err
83-
times.append(None)
63+
if isinstance(format, list):
64+
for element in arg:
65+
for fmt in format:
66+
try:
67+
times.append(datetime.strptime(element, fmt).time())
68+
break
69+
except (ValueError, TypeError):
70+
continue
71+
else:
72+
if errors == "raise":
73+
msg = (
74+
f"Cannot convert {element} to a time with given "f"formats {format}")
75+
raise ValueError(msg)
76+
times.append(None)
77+
else:
78+
for element in arg:
79+
try:
80+
times.append(datetime.strptime(element, format).time())
81+
except (ValueError, TypeError) as err:
82+
if errors == "raise":
83+
msg = (f"Cannot convert {element} to a time withgiven "f"format {format}")
84+
raise ValueError(msg) from err
85+
times.append(None)
8486
else:
85-
formats = _time_formats[:]
86-
format_found = False
87+
formats = _time_formats + (custom_formats or [])
8788
for element in arg:
8889
time_object = None
8990
try:
@@ -92,22 +93,15 @@ def _convert_listlike(arg, format):
9293
for time_format in formats:
9394
try:
9495
time_object = datetime.strptime(element, time_format).time()
95-
if not format_found:
96-
# Put the found format in front
97-
fmt = formats.pop(formats.index(time_format))
98-
formats.insert(0, fmt)
99-
format_found = True
10096
break
10197
except (ValueError, TypeError):
10298
continue
103-
10499
if time_object is not None:
105100
times.append(time_object)
106101
elif errors == "raise":
107102
raise ValueError(f"Cannot convert arg {arg} to a time")
108103
else:
109104
times.append(None)
110-
111105
return times
112106

113107
if arg is None:
@@ -121,7 +115,6 @@ def _convert_listlike(arg, format):
121115
return _convert_listlike(arg, format)
122116
elif is_list_like(arg):
123117
return _convert_listlike(arg, format)
124-
125118
return _convert_listlike(np.array([arg]), format)[0]
126119

127120

@@ -149,5 +142,4 @@ def _guess_time_format_for_array(arr):
149142
return time_format
150143
except ValueError:
151144
pass
152-
153145
return None

0 commit comments

Comments
 (0)