
On Wed, Jan 5, 2011 at 10:50 PM, Guido van Rossum <guido@python.org> wrote: ..
I propose to change that to
if y < 1000: if accept2dyear: if 69 <= y <= 99: y += 1900 elif 0 <= y <= 68: y += 2000 else: raise ValueError("year out of range") # call system function with tm_year = y - 1900
The new logic doesn't look right, am I right that this is what you meant?
if accept2dyear and 0 <= y < 100: (convert to year >= 1970) if y < 1000: raise ...
Not quite. My proposed logic would not do any range checking if accept2dyear == 0.
But what guarantees do we have that the system functions accept negative values for tm_year on all relevant platforms?
I've already committed an implementation of asctime, so time.asctime and time.ctime don't call system functions anymore. This leaves time.mktime and time.strftime. The latter caused Tim Peters to limit year range to >= 1900 eight years ago: http://svn.python.org/view?view=rev&revision=30224 For these functions, range checks are necessary only when system functions may crash on out of range values. If we can detect error return and convert it to an exception, there is no need to look before you leap. (Note that asctime was different because the relevant standards specifically allowed it to have undefined behavior for out of range values.) I cannot rule out that there are systems out there with buggy strftime, but the situation has improved in the last eight years and we have buildbots and unittests to check behavior on relevant platforms. If we do find a platform with buggy strftime which crashes or produces nonsense with negative tm_year, we can add a platform specific range check to work around platform bug, or just ask users to bug their OS vendor. :-)
The 1000 limit still seems pretty arbitrary to me -- if it's only because you don't want to decide whether to use leading spaces or zeros for numbers shorter than 4 digits, let me propose leading zeros since we use those uniformly for months, days, hours, minutes and seconds < 10,
Except we don't:
time.asctime((2000, 1, 1, 0, 0, 0, 0, 0, -1)) 'Sat Jan 1 00:00:00 2000'
(note that day is space-filled.) I am not sure, however, what you are proposing here. Are you arguing for a wider or a narrower year range? I would be happy with just if accept2dyear: if 69 <= y <= 99: y += 1900 elif 0 <= y <= 68: y += 2000 # call system function with tm_year = y - 1900 but I thought that would be too radical.