-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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.strftime("%Y") not consistent for years < 1000 #57514
Comments
on linux
>>> datetime(1, 2, 10, 11, 41, 23).strftime("%Y")
'1'
on osx
>>> datetime(1, 2, 10, 11, 41, 23).strftime("%Y")
'0001'
>>> datetime.strptime('0001', '%Y')
datetime.datetime(1, 1, 1, 0, 0)
>>> datetime.strptime('1', '%Y')
ValueError: time data '1' does not match format '%Y' |
FWIW, issue bpo-1777412 added support for years < 1000 to Python 3.3 strftime. |
I am not sure this can be fixed without distributing our own implementation of strftime. See bpo-3173. |
There's many discrepancies between OS X and Linux about time formatting... OS X
>>> from datetime import datetime
>>> datetime(1900, 1, 1).strftime("%6Y")
'6Y'
Linux
>>> from datetime import datetime
>>> datetime(1900, 1, 1).strftime("%6Y")
'001900' BTW, these discrepancies are already mentioned: “The full set of format codes supported varies across platforms, because Python calls the platform C library’s strftime() function, and platform variations are common.” We should had an asterisk to the "%Y" saying that the padding is not consistent across platforms. |
Proposed patch to fix the issue in xmlrpc.client |
New changeset 3f025427f02b by Florent Xicluna in branch 'default': |
Le 01/11/2011 00:07, Roundup Robot a écrit :
I don't like this hack. If there is a bug in time.strftime(), we need to Is there a test for the hack? |
New changeset 230f0956aaa3 by Florent Xicluna in branch 'default': |
Did your commit fix the issue or not? |
I understand that the issue is because the C standard does not specify the length of the string returned by '%Y'. The changeset 230f0956aaa3 adds a test to verify that either '%Y' or '%4Y' returns a 4-digits value usable to produce ISO-8601 representations. Now it is a documentation issue: add a comment to the "%Y" specifier saying that the padding is not applicable to all platforms and in such case the "%4Y" specifier should return the 4-digit value. |
Since the changeset 55a3b563f0dbed04af317f632f7f3c0f6abe175b, test_strptime is failing on "AMD64 Gentoo Wide 3.x" buildbot: ====================================================================== Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.ochtman-gentoo-amd64/build/Lib/test/test_time.py", line 159, in test_strptime
time.strptime(strf_output, format)
ValueError: time data 'LMT' does not match format '%Z'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.ochtman-gentoo-amd64/build/Lib/test/test_time.py", line 162, in test_strptime
(format, strf_output))
AssertionError: conversion specifier '%Z' failed with 'LMT' input. http://www.python.org/dev/buildbot/all/builders/AMD64%20Gentoo%20Wide%203.x/builds/2661 |
Can someone recap the status of this issue? It is classified as a documentation bug, but I don't see a clear statement of what is wrong with the documentation. |
See msg146972 -- AFAIU the padding of %Y is inconsistent for years <1000 (e.g. 0042 vs 42), and this is not documented in the note (2) of https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior |
At the bottom of <https://docs.python.org/dev/library/time.html#time.strftime\> it suggests that this four-digit field width specifier is not portable. Does that also hold for the datetime version? It seems like a bad idea to recommend an unportable workaround for a portability problem. Also, in the patch it is not clear if you are referring to strptime(), strftime(), or both. On Linux, datetime.strptime(..., "%4Y") fails for me. |
Actually I was wrong. Based on some more testing I did on Linux and Windows 8 and the previous comments in this thread, it seems that, with 1 as year:
So the problem is only on Linux and only with years <1000, where to have a zero-padded value %4Y can be used instead.
|
I submitted a patch for documentation changes related to strftime "%Y" directive inconsistencies. I am not sure that specifying the OS is correct, because I haven't tested the inconsistencies on all Linux PCs, Windows versions or OS X. I still left them there though, so let me know what's your opinion on it. |
New changeset 291d47954618 by Victor Stinner in branch 'default': |
About Elena Oat's patch bpo-13305.diff: I'm not sure that strftime("%4Y") works on all platforms, so I enabled the test on strftime("%4Y"). I will check our buildbots. |
acucci's patch doc.patch suggests to use format "%4Y". Problem: I tried it on Linux, and it looks like it doesn't work. >>> datetime.datetime.strptime("1980", "%Y")
datetime.datetime(1980, 1, 1, 0, 0)
>>> datetime.datetime.strptime("1980", "%4Y")
Traceback (most recent call last):
...
ValueError: '4' is a bad directive in format '%4Y' Or maybe I misunderstood the doc change. Do you suggest to use %4Y format with strptime(), with strftime() or with both? |
It doesn't, that's what the patch is trying to document. |
Oh. I confirm: %4Y gives "4Y" for any year on FreeBSD and Mac OS X, it raises ValueError("Invalid format string") on Windows, etc. |
Elena's bpo-13305.diff: "Zero padding can be forced on some platforms by using e.g. Sorry, I still doesn't understand the change. %4Y doesn't work with strptime() and it only work with strftime() on very few platforms. Can you explain when %4Y should be used? strftime() and/or strptime()? Which platform? To me, it looks wrong to document %4Y since it almost never works... |
New changeset e54224e8d6a9 by Victor Stinner in branch 'default': |
(See also msg307413 (#76376 (comment)) in duplicate bpo-32195 for more discussion.) |
In bpo-39103, I filed a bug relating to this issue. I'd like for Python to provide a portable implementation of strftime instead of just documenting that the version isn't portable. Given that this ticket assigned to 'docs' suggests that a portable version is out of the question. Can we expand the scope of this issue to actually providing a portable version? |
If someone wants to do that, I suggest to first start with a project on PyPI. It sounds like a tricky project. Date, time, locales and localization are hard problems! |
This also causes an issue when using stftime and strptime together on Linux (Ubuntu 20.04.1 LTS). Example:
>>> pattern = "%Y-%m-%d"
>>> datetime.strptime(
... datetime(1, 1, 1).strftime(pattern),
... pattern
... )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/lib/python3.8/_strptime.py", line 349, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '1-01-01' does not match format '%Y-%m-%d' |
Has there been any work/progress on this? Alternatively, what suggested work around/mitigations are suggested? |
The tempora library implements a portable strftime. |
Given the age of the ticket and the lack of clarity on what to do, I don't think the "easy" label still applies here, does it? :-) |
The wrapper in tempora has worked well for me for a couple of years. It defers most of the processing to the existing C implementation and merely performs the substitution early, allowing the C implementation to handle the rest. Would it make sense for CPython to adopt a similar technique to address the concern at hand and avoid doing a full re-implementation (with all of the bugs and performance regressions that would likely entail)? |
A fix for The issue is now resolved with PR #120820 by conditionally delegating the said format specifiers to |
Closing as a duplicate of #120713. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: