GeezerVison is showing github.com — `datetime.strftime("%Y")` is not padding correctly · Issue #120713 · python/cpython
datetime.strftime("%Y") is not padding correctly #120713
DescriptionBug report
Bug description:
docs say:
%Y
Year with century as a decimal number.
0001, 0002, …, 2013, 2014, …, 9998, 9999
but this is what is happening
from datetime import datetime
print(datetime(9, 6, 7).strftime("%Y-%m-%d")) # 9-06-07
print(datetime(99, 6, 7).strftime("%Y-%m-%d")) # 99-06-07
print(datetime(999, 6, 7).strftime("%Y-%m-%d")) # 999-06-07
CPython versions tested on:
3.10
Operating systems tested on:
No response
Linked PRs
Activityblhsing commented on Jun 19, 2024 Reproducible on 3.10 but not on 3.11+. serhiy-storchaka commented on 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 commented on Jun 19, 2024
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:
According to the doc:
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.
serhiy-storchaka commented on 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. blhsing commented on Jun 21, 2024 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. serhiy-storchaka commented on 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 commented on 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.
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. blhsing commented on Jun 24, 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.
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. blhsing commented on Sep 4, 2024
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. serhiy-storchaka commented on Sep 4, 2024 Please open a new issue and provide more details. picnixz commented on Sep 4, 2024 Reacted by Serhiy Storchaka
MetadataMetadataStatusShow more project fields
DevelopmentNo branches or pull requestsIssue actions
|