You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
datetime.strftime("%Y") is not padding correctly #120713
I wonder whether this is a documentation issue or the output is platform depending.
Ah, so the issue is platform-dependent. When I reproduced the OP's issue in 3.10 I was doing it in Linux, while in Windows I tested the code in 3.11 and 3.13 and the issue was not reproduced. Now I realized that this is just a result of datetime.strftime being a thin wrapper over the platform's strftime in the C library:
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. To see the full set of format codes supported on your platform, consult the strftime(3) documentation.
The limitation for year >= 1000 was removed in bpo-11930 (gh-56139). But there were various problems with the newly added test test_strftime_y2k, it required several corrections.
For now, we cannot guarantee the result for %Y (and %G) with year < 1000. It is especially bad since strptime()requires the year to be 4 digits.
Since datetime.strftime already uses a wrapper function to handle format specifiers not conforming to the C strftime, I think a reasonable fix would be to add the translation of %Y to %4Y there as needed by the platform to make the function portable.
Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.
Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.
With PR #120820 I've made sure that the translation is only used when explicitly supported by the platform so that it is at least an improvement and not a regression in any case. I did just revert my changes to the unit test to allow an outlier platform to pass the test.
Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.
On second thought, guaranteeing 4 digits is actually not complex since we can simply format the year with "%04ld" using sprintf, which works on all platforms.
I've updated the PR accordingly so that a 4-digit year with century can now be guaranteed.
I'm not sure why but we are seeing failures on JIT for the test_strftime_y2k on emulated Linux. Is it because emulated Linux have (yet) another weird case of glibc?
Thanks for the heads-up. It is weird indeed that this can happen since according to the build log the configure script did detect that the platform would not 0-pad a century so the handler for %Y would format the year itself with snprintf using the "%04ld" format string.
Since this happens only on aarch64 perhaps there is indeed some peculiarity of snprintf in the glibc of that platform.
Will try debugging this on a Mac later.
Also, the reason we reverted the commits on 3.12 and 3.13 was because it was more of a feature than a bugfix?
It's a bug fix but was found to be incomplete, due to issue #122272.
Activity
blhsing commentedon Jun 19, 2024
Reproducible on 3.10 but not on 3.11+.
serhiy-storchaka commentedon Jun 19, 2024
cc @pganssle
I suppose that it works in such way since Python 3.0 (I tested in 3.3). 2.7 does not support years before 1900.
You can use %4Y to always get 4-digit year. I wonder whether this is a documentation issue or the output is platform depending.
blhsing commentedon Jun 19, 2024
Ah, so the issue is platform-dependent. When I reproduced the OP's issue in 3.10 I was doing it in Linux, while in Windows I tested the code in 3.11 and 3.13 and the issue was not reproduced. Now I realized that this is just a result of
datetime.strftimebeing a thin wrapper over the platform'sstrftimein the C library:According to the doc:
serhiy-storchaka commentedon Jun 20, 2024
The limitation for year >= 1000 was removed in bpo-11930 (gh-56139). But there were various problems with the newly added test
test_strftime_y2k, it required several corrections.For now, we cannot guarantee the result for %Y (and %G) with year < 1000. It is especially bad since
strptime()requires the year to be 4 digits.pythongh-120713: normalize year with century for datetime.strftime
pythongh-120713: fixed pyconfig.h.in
blhsing commentedon Jun 21, 2024
Since
datetime.strftimealready uses a wrapper function to handle format specifiers not conforming to the Cstrftime, I think a reasonable fix would be to add the translation of%Yto%4Ythere as needed by the platform to make the function portable.serhiy-storchaka commentedon Jun 21, 2024
Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.
blhsing commentedon Jun 21, 2024
With PR #120820 I've made sure that the translation is only used when explicitly supported by the platform so that it is at least an improvement and not a regression in any case. I did just revert my changes to the unit test to allow an outlier platform to pass the test.
pythongh-120713: format "%Y" with "%4d" using sprintf instead of repl…
pythongh-120713: test that a 0-padded year with century is guaranteed
blhsing commentedon Jun 24, 2024
On second thought, guaranteeing 4 digits is actually not complex since we can simply format the year with
"%04ld"usingsprintf, which works on all platforms.I've updated the PR accordingly so that a 4-digit year with century can now be guaranteed.
pythongh-120713: revised detection logics in Python
51 remaining items
blhsing commentedon Sep 4, 2024
Thanks for the heads-up. It is weird indeed that this can happen since according to the build log the configure script did detect that the platform would not 0-pad a century so the handler for
%Ywould format the year itself withsnprintfusing the"%04ld"format string.Since this happens only on
aarch64perhaps there is indeed some peculiarity ofsnprintfin the glibc of that platform.Will try debugging this on a Mac later.
It's a bug fix but was found to be incomplete, due to issue #122272.
serhiy-storchaka commentedon Sep 4, 2024
Please open a new issue and provide more details.
picnixz commentedon Sep 4, 2024
See #123681.
pythongh-120713: Make _Py_NORMALIZE_CENTURY private
gh-120713: Make _Py_NORMALIZE_CENTURY private (GH-135933)
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
[3.14] gh-120713: Make _Py_NORMALIZE_CENTURY private (GH-135933) (#13…
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)
Work around Python strftime bug
icloudpd: build with python313
fix: zero-pad early creation years on the detail page