On 1/28/19, David Raymond <david.raym...@tomtom.com> wrote: > > In the docs there is > "0 is a legal argument for any position in the time tuple; if it is normally > illegal the value is forced to a correct one."
The POSIX specification for strftime only states that "[i]f any of the specified values are outside the normal range, the characters stored are unspecified" [1]. Python tries to bring some semblance of order across the various implementations of this function. For tm_year, it was eventually decided circa Python 3.2 to support the full signed range on most platforms, even if isn't a normal date, such as year 0 and negative year values. For example, in 3.6.7 in Linux: >>> time.strftime("%Y = %C * 100 + %y", (0, 0, 0, 0, 0, 0, 0, 0, 0)) '0 = 0 * 100 + 00' >>> time.strftime("%Y = %C * 100 + %y", (-10, 0, 0, 0, 0, 0, 0, 0, 0)) '-10 = -1 * 100 + 90' 2.7.15 in Linux has different behavior, especially if time.accept2dyear is true (set by default unless the environment variable PYTHONY2K is defined). >>> time.accept2dyear 1 >>> time.strftime("%Y = %C * 100 + %y", (0, 0, 0, 0, 0, 0, 0, 0, 0)) '2000 = 20 * 100 + 00' >>> time.strftime("%Y = %C * 100 + %y", (-10, 0, 0, 0, 0, 0, 0, 0, 0)) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: year out of range The magical year value of 2000 comes from code to support pre-Y2K scripts that assume years 69-99 are 1969-1999 and years 0-68 are 2000-2068. If we force time.accept2dyear to false, we see that Python 2 actually requires the year to be at least 1900. >>> time.accept2dyear = 0 >>> time.strftime("%Y = %C * 100 + %y", (0, 0, 0, 0, 0, 0, 0, 0, 0)) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: year >= 1900 required > and yet if given 0 for the year/first item in the tuple it raises a > ValueError. > > Is that a bug in the code, the documentation, or my understanding? It's not a bug. However, in recent versions of the Windows C runtime, "%y" does support year values down to 0 (but not negative years), so the check [2] can be relaxed down to 0 (whatever year 0 is supposed to be), and the additional check for "%y" can be removed [3]. [1]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html [2]: https://github.com/python/cpython/blob/v3.7.2/Modules/timemodule.c#L721 [3]: https://github.com/python/cpython/blob/v3.7.2/Modules/timemodule.c#L760 -- https://mail.python.org/mailman/listinfo/python-list