Skip to content

datetime.fromisoformat() only accepts 3 or 6 decimal places for fractional seconds #95221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rdfguy opened this issue Jul 24, 2022 · 5 comments
Closed
Assignees
Labels
3.10 only security fixes

Comments

@rdfguy
Copy link

rdfguy commented Jul 24, 2022

The ISO 8601 spec allows any number of decimal places for fractional seconds, but the datetime.fromisoformat() method raises a ValueError if there is a fractional part that has something other than 3 or 6 decimal places (I checked the source code). This causes problems with, for example, Adobe XMP metadata.

This raises a ValueError:

import datetime
datetime.datetime.fromisoformat("2021-06-26T08:34:41.12-05:00")  # only two decimal places

Tested in this environment:

Python 3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) 
[Clang 6.0 (clang-600.0.57)] on darwin
@rdfguy rdfguy added the type-bug An unexpected behavior, bug, or error label Jul 24, 2022
@tiran
Copy link
Member

tiran commented Jul 25, 2022

2021-06-26T08:34:41.12-05:00 is an ISO format string with a time zone (-05:00, probably eastern standard time). The datetime.fromisoformat() method does not support ISO format strings with time zones:

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat

This does not support parsing arbitrary ISO 8601 strings - it is only intended as the inverse operation of datetime.isoformat(). A more full-featured ISO 8601 parser, dateutil.parser.isoparse is available in the third-party package dateutil.

@rdfguy
Copy link
Author

rdfguy commented Jul 25, 2022

Except that it does support time zones. The only real limitation I have found, namely that only 3 or 6 decimal places for the fractional second is allowed, is rather arbitrary and causes the function to fail when parsing ISO date stamps produced by other systems. There is no good justification for this, and it would be easy to fix.

@markaidev
Copy link

I verified the bug exists in old versions of python, but when I forked, compiled, and made it from the newest source, the errors are gone. I am new to this codebase so maybe I missed something, but it seems to be fixed somehow.

@abalkin
Copy link
Member

abalkin commented Feb 8, 2023

It looks like this was fixed in 3.11:

Python 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> print(datetime.datetime.fromisoformat("2021-06-26T08:34:41.12-05:00"))
2021-06-26 08:34:41.120000-05:00

See GH-80010.

CC: @pganssle

@abalkin abalkin added 3.10 only security fixes and removed type-bug An unexpected behavior, bug, or error labels Feb 8, 2023
@abalkin
Copy link
Member

abalkin commented Feb 8, 2023

As @tiran noted above, the limitation was intentional when the fromisoformat method was introduced in 3.7 and well-documented. See GH-60077. The supported format prior to 3.11 was

YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]

See datetime.fromisoformat. Since the requested behaviour is already implemented in 3.11, I am closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 only security fixes
Projects
Archived in project
Development

No branches or pull requests

4 participants