-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
datetime library doesn't support valid ISO-8601 alternative for midnight #102450
Comments
From the referenced wikipedia page:
Looking at the datetime commit log, I am pretty sure that 24:00:00 support was not removed after the 2019 version but was never there. It is obviously a nuisance. While the doc for datetime.datetime explicitly disclaims such support ("0 <= hour < 24"), the doc for datetime.datetime.fromisoformat does not. It says "Return a datetime corresponding to a date_string in any valid ISO 8601 format, with the following exceptions:" and lists 4 exceptions. To me, the bug here is the omission of the pretty clearly intended '240000' exception. The fix would be to add the 5th exception to the doc. The request to add support would then be a feature addition. I have no opinion, but think it less likely to be accepted than rejected. |
See also #54636 |
I think this actually is a bug. The original intention was that Support for 24 as an alternative to midnight doesn't really fit into that category, and can be useful in certain situations, so I'd be happy to see a PR for this. |
I agree with you that this is something I feel is a bug and I'd like to see added, even with the points mentioned by @terryjreedy. To that end, I'd be interested in writing the PR for this. Code wise, is it just the I suppose documentation would also need to be updated, but I'm not sure how to do this. It seems the queries in #54636 were addressed, but just to confirm, I'd expect |
What about |
No, we shouldn't make it so that I think you want to update You will also want to add test cases to
This proposal should have no effect on the |
According to the Wikipedia quote above, time Just to explain where I ran into it, I work on a system which defines "parts of day" like this (for example):
This is in a PostgreSQL database using the So the two midnights look like different things to me, I don't think |
I mean, the alternative is that it doesn't parse at all and you simply cannot represent the last interval, so it doesn't work either way. At least if the parse works, you have the option to find a different way to represent that interval. |
Does this mean you're saying that I was originally envisioning something along the lines of def the_datetime_primary_constructor(year, month, day, hour, second, microsecond):
if (hour == 24):
if (second == microsecond == 0):
hour = 0
day += 1 # with the correct handling for "rollover", i.e. adjusting month/year as necessary.
else:
raise ValueError("For hour to be 24, second and microsecond must be 0.")
... This means that |
Yes, I'm saying precisely this. The main constructor and underlying data model does not have anything to do with ISO 8601. Consider that Also, I will note my bias here: ISO 8601 is an annoying and awful spec. It's proprietary and not even freely available. It's ridiculously convoluted and so expansive that no parser I know of implements the whole spec. Despite the byzantine complexity, it is also vague about things like what the date-time separator can be or how many digits can come after the fraction separator and it has no provision for things like fractional offsets. RFC3339 tries to tame the complexity but is only acceptable for representing absolute times. No one understands the ISO week calendar, either. Everyone thinks they like ISO 8601 because YYYY-MM-DD is a good way to represent dates, and people have converged on that, but if I could I would burn ISO 8601 to the ground and start over (sure we'd probably also get some weird camel of a format designed by committee, but at least if we did it today it would be in the public domain). Needless to say, the fact that ISO 8601 does some weird thing is not a good argument for importing that particular abstraction. It's probably a good argument for including it in |
Yeah, fair enough. I'll go ahead and work on a PR just for the change to |
I'm having some issues with "building" changes that I'm making to the python files. I found the contributing guide section on building, and followed that, but my changes to the Steps I'm doing:
>>> import datetime
>>> datetime.datetime.fromisoformat("2022-01-01 00:00:00") The above steps don't appear to result in the According to the note in the dev guide, I shouldn't need to build for changes to python code, but figured I'd try that when it didn't seem to work. Can I please get some assistance? |
This isn't the best place to get help with this, probably something on discuss.python.org would be better. But as a hint, the code is probably in Modules/_datetimemodule.c. |
To be clear, the code is in both, @TizzySaurus Feel free to make a draft PR and ping me on it. |
Yes, @pganssle is correct. Thanks for the PEP reference, I couldn't find it quickly. |
… calls. (#105856) * Add NEWS.d entry * Allow ISO-8601 24:00 alternative to midnight on datetime.time.fromisoformat() * Allow ISO-8601 24:00 alternative to midnight on datetime.datetime.fromisoformat() * Add NEWS.d entry * Improve error message when hour is 24 and minute/second/microsecond is not 0 * Add tests for 24:00 fromisoformat * Remove duplicate call to days_in_month() by storing in variable * Add Python implementation * Fix Lint * Fix differing error msg in datetime.fromisoformat implementations when 24hrs has non-zero time component(s) * Fix using time components inside tzinfo in Python implementation * Don't parse tzinfo in C implementation when invalid iso midnight * Remove duplicated variable in datetime test assertion line * Add self to acknowledgements * Remove duplicate NEWS entry * Linting * Add missing test case for when wrapping the year makes it invalid (too large)
* main: (69 commits) Add "annotate" SET_FUNCTION_ATTRIBUTE bit to dis. (python#124566) pythongh-124412: Add helpers for converting annotations to source format (python#124551) pythongh-119180: Disallow instantiation of ConstEvaluator objects (python#124561) For-else deserves its own section in the tutorial (python#123946) Add 3.13 as a version option to the crash issue template (python#124560) pythongh-123242: Note that type.__annotations__ may not exist (python#124557) pythongh-119180: Make FORWARDREF format look at __annotations__ first (python#124479) pythonGH-58058: Add quick reference for `ArgumentParser` to argparse docs (pythongh-124227) pythongh-41431: Add `datetime.time.strptime()` and `datetime.date.strptime()` (python#120752) pythongh-102450: Add ISO-8601 alternative for midnight to `fromisoformat()` calls. (python#105856) pythongh-124370: Add "howto" for free-threaded Python (python#124371) pythongh-121277: Allow `.. versionadded:: next` in docs (pythonGH-121278) pythongh-119400: make_ssl_certs: update reference test data automatically, pass in expiration dates as parameters python#119400 (pythonGH-119401) pythongh-119180: Avoid going through AST and eval() when possible in annotationlib (python#124337) pythongh-124448: Update Windows builds to use Tcl/Tk 8.6.15 (pythonGH-124449) pythongh-123884 Tee of tee was not producing n independent iterators (pythongh-124490) pythongh-124378: Update test_ttk for Tcl/Tk 8.6.15 (pythonGH-124542) pythongh-124513: Check args in framelocalsproxy_new() (python#124515) pythongh-101100: Add a table of class attributes to the "Custom classes" section of the data model docs (python#124480) Doc: Use ``major.minor`` for documentation distribution archive filenames (python#124489) ...
It will be in 3.14. |
Bug report
According to ISO-8601, a time of
24:00
on a given date is a valid alternative to00:00
of the following date, however Python does not support this, raising the following error when attempted:ValueError: hour must be in 0..23
.This bug can be seen from multiple scenarios, specifically anything that internally calls the
_check_time_fields
function, such as the following:The fix for this is relatively simple: have an explicit check within
_check_time_fields
for the scenario wherehour == 24 and minute == 0 and second == 0 and microsecond == 0
, or more conciselyhour == 24 and not any((minute, second, microsecond))
, and in this scenario increase the day by one (adjusting the week/month/year as necessary) and set the hour to 0.I imagine the
check_time_args
C function would also have to be updated.Your environment
Linked PRs
fromisoformat()
calls. #105856The text was updated successfully, but these errors were encountered: