-
-
Notifications
You must be signed in to change notification settings - Fork 33.3k
Description
Feature or enhancement
I propose that a new % format code(s) be added to strptime to allow parsing of timestamps which are either whole seconds, or fractions of a second.
The current %f format code will throw an error if the input string has no microsecond component.
Pitch
As an example, I would like to pass both of the following strings with the same code.
import datetime as dt
fmt = "%Y-%m-%d %H:%M:%S.%f"
ts = [
"2023-01-01 09:10:13.513",
"2023-01-01 09:10:13"
]
for s in ts:
dt.datetime.strptime(s, fmt)This currently fails with:
Traceback (most recent call last):
File "main.py", line 9, in <module>
dt.datetime.strptime(s, fmt)
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/_strptime.py", line 349, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '2023-01-01 09:10:13' does not match format '%Y-%m-%d %H:%M:%S.%f'In my code I could write a try/except block to catch the error and try with a different string. I think it would be nice if strptime could handle that for me. Although I do know that the implementation of this function depends on the system, so this might be a tricky change.
There's a few options.
Option A
Add a new format code which is similar to %f, but can handle an empty microsecond component.
I note that %F is not yet taken, so we could use that.
Note that %f today doesn't expect a ..
So in the above example you'd use %Y-%m-%d %H:%M:%S%F.
Option B
Add a new format code for parsing seconds and optionally microseconds in one go. I note that %s is not yet taken, so we could use that.
So in the above example you'd use %Y-%m-%d %H:%M:%s.
Option C
Add [] to make a component optional.
So in the above example you'd use %Y-%m-%d %H:%M:%S[.%f].
My guess is that this would be quite a substantial change.
Option D
Modify the arguments to strptime so that it can take a list of format strings. It tries them in order until it one succeeds.
So in the above example you'd use
dt.datetime.strptime(s, ["%Y-%m-%d %H:%M:%S.%f", "%Y-%m-%d %H:%M:%S"])Since a list of strings, and a single string are both iterators of strings, this might be a bit fiddly to implement. You could add a new formats argument, and require that either format or formats is passed in. Although that kind of clutters the function signature.
Previous discussion
https://bugs.python.org/issue1982 @abalkin
https://bugs.python.org/issue1158
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status