classification
Title: datetime.strftime dislikes years before 1900
Type: enhancement Stage: commit review
Components: Library (Lib) Versions: Python 3.2
process
Status: closed Resolution: fixed
Dependencies: 7989 10827 Superseder:
Assigned To: belopolsky Nosy List: belopolsky, benno, davidfraser, eric.araujo, georg.brandl, giampaolo.rodola, haypo, kiorky, loewis
Priority: normal Keywords: patch

Created on 2007-08-20 03:36 by benno, last changed 2011-01-08 16:40 by haypo. This issue is now closed.

Files
File name Uploaded Description Edit
strftime-pre-1900.patch davidfraser, 2008-05-10 15:35 patch to use strftime directly from datetime instead of going through the time module, and remove the pre-1900 restriction review
strftime-pre-1900.patch kiorky, 2010-10-08 04:37
issue1777412.diff belopolsky, 2011-01-07 22:59
datetime_strftime_nolimit.diff haypo, 2011-01-08 00:26
strftime_1_9999.patch haypo, 2011-01-08 01:36
Messages (26)
msg55156 - (view) Author: Benno Rice (benno) Date: 2007-08-20 03:36
Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) 
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.date(1876, 2, 3).strftime('%Y-%m-%d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year=1876 is before 1900; the datetime strftime() methods require year >= 1900


Apparently this is due to platform-specific weirdnesses in implementations of strftime.  It is still very annoying however.  Perhaps a good implementation of strftime could be found and incorporated into Python itself?
msg55157 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2007-08-21 08:15
This is not a bug report, but a feature request. Python works correctly as-is.
msg66535 - (view) Author: David Fraser (davidfraser) Date: 2008-05-10 15:35
I have a patch for this, but I don't know which platforms have the
problem. On Linux, strftime seems to work fine. Attaching the patch as a
work in progress...
msg66541 - (view) Author: Skip Montanaro (skip.montanaro) * (Python committer) Date: 2008-05-10 16:45
Which version of Python are you using?  I could have sworn we just fixed
this problem in CVS a couple weeks ago.
msg66584 - (view) Author: David Fraser (davidfraser) Date: 2008-05-10 20:41
> Which version of Python are you using?  I could have sworn we just fixed
this problem in CVS a couple weeks ago.
This was on the latest Python 2.6 svn... but looking at the py3k branch
with viewsvn the code is definitely still there too...

The relevant commit seems to be r30224 in 2002:
> I give up:  unless I write my own strftime by hand, datetime just can't
be trusted with years before 1900, so now we raise ValueError if a date or
datetime or datetimetz .strftime() method is called with a year before
1900.

Of course I'm not dealing with any of this in the attached patch, but
then I don't have the information on which platforms have the problem...
but according to the above writing strftime by hand would be the only
solution...
msg66585 - (view) Author: Skip Montanaro (skip.montanaro) * (Python committer) Date: 2008-05-10 21:04
Ah, I remember now.  It was a special case for xmlrpclib to allow
its Date objects to operate before 1900.
msg75727 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-11-11 03:50
The patch doesn't work on Python3 because Python3 changes 
time.strftime() for year < 1900: if time.accept2dyear is not False (or 
not set), raise an error; otherwise convert 0..68 => 2000..2068, 
69..99 => 1968..1999, or raise an error.
msg75731 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-11-11 04:11
See also issue #3173.
msg100163 - (view) Author: kiorky (kiorky) Date: 2010-02-26 16:36
I made this patch apply on release24-maint as i need python24 for my projects.

You can find the following patch there:
http://git.minitage.org/git/minitage/buildouts/dependencies/python-2.4.6/tree/patches/strftime-pre-1900.patch

I successfully used it on some linux26 box.
msg100165 - (view) Author: kiorky (kiorky) Date: 2010-02-26 16:36
And forgotten to say that it worked for me for py26 and py24.
msg107167 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2010-06-06 00:22
I see this in py3k branch on MacOS X:

[GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> datetime.date(1876, 2, 3).strftime('%Y-%m-%d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year=1876 is before 1900; the datetime strftime() methods require year >= 1900


I like the approach taken in the David's patch.  The datetime module should stop piggybacking on the time module.
msg110792 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2010-07-19 18:19
Adding issue7989 as a dependency because one of the stated reasons for not calling system strftime from datetime directly is because pure python implementations cannot do the same.  This of course can be resolved by exposing raw strftime in separate module (for example _time), but simply applying this patch before #7989 would mean that year < 1900 would have to be disabled for pure python implementation tests.
msg118163 - (view) Author: kiorky (kiorky) Date: 2010-10-08 04:37
This patch doesnt apply anymore on py26.
Joining an updated patch.
msg118212 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2010-10-08 18:39
kiorky,

Thank you for the updated patch, but since it implements a new feature, it cannot be applied to 2.x series.  I am +1 on removing year > 1900 limitation from datetime.strftime in 3.x, but you need to consider how this can be achieved in pure python datetime implementation which is now slated to be released in 3.2.  See msg110792 above.
msg118328 - (view) Author: kiorky (kiorky) Date: 2010-10-10 09:46
We must not have the same point of view about new features and bugfixes...
msg118331 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2010-10-10 10:08
kiorky: see my msg55157. Python behaves correctly as it stands - raising the exception is fully intentional. It's not a bug that it gets raised; dates before 1900 are just not supported. Adding support for them is a new feature.
msg125478 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-05 23:19
I would like to push this for 3.2.  Recent discussions at issue10827 and on python-dev seem to favor removal of arbitrary limits on year range.
msg125725 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-07 22:59
After r87829 (see issue10827), the insane Y2K behavior of time module functions does not extend beyond year 999.  Hopefully in Python 3.3, accept2dyear will be removed completely and datetime.strftime() will be able to support the full intersection of platform year range with that of datetime type.  Meanwhile, I propose a simple patch that lowers the 1900 limit down to 1000.  I was not able to find any evidence that there are platforms that have issues with formatting years between 1000 and 1899.

Are there any objections to committing this patch?  I will monitor the build bots if I see failures, I'll modify the test and/or add a platform-specific check to fix them.
msg125736 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-01-08 00:26
Here is a patch removing the arbitrary datetime.strftime() limit on year: it adds an option "accept2dyear" to time.strftime() and datetime just sets this option to False.
msg125738 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-08 01:08
On Fri, Jan 7, 2011 at 7:26 PM, STINNER Victor <report@bugs.python.org> wrote:
..
> Here is a patch removing the arbitrary datetime.strftime() limit on year: it adds an
> option "accept2dyear" to time.strftime() and datetime just sets this option to False.
>

The idea of adding an optional argument to  time.strftime() was
discussed on python-dev, but did not get much traction there:

"""
I wish we didn't have to do that -- isn't it easy enough for the app
to do the 2d -> 4d conversion itself before calling the library
function? The only exception would be when parsing a string -- but
strptime can tell whether a 2d or 4d year is requested by the format
code (%y or %Y).
msg125740 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-08 01:34
--
--Guido van Rossum (python.org/~guido)
"""  -- http://mail.python.org/pipermail/python-dev/2011-January/107246.html

^^^ the last lines of msg125738 cut by roundup ^^^
msg125741 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-01-08 01:36
strftime_1_9999.patch: replace 1900 <= year limit by 1 <= year or 1 <= year <= 9999 (if compiled with Visual Studio). With more tests on years.
msg125742 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-08 01:49
I like strftime_1_9999.patch, but it really belongs to #10827.  Please leave a note there once you commit and mention the issue in commit log.
msg125743 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-01-08 02:01
r87845+r87846 sets time.strftime() minimum year to 1 instead of 1900. If Python is compiled with Visual Studio, it sets also the maximum year to 9999.
msg125748 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-01-08 03:39
> r87845+r87846 sets time.strftime() minimum year to 1 instead of 1900.
> If Python is compiled with Visual Studio, it sets also the maximum 
> year to 9999.

r87848 removes all limits on the year field; r87850 (Issue #10864) limits year to [1; 9999] on Solaris.
msg125792 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2011-01-08 16:40
time.asctime(), time.ctime() and time.strftime() are no more not limited for the year field if accept2dyear=0. Except with Visual Studio or on Solaris: the year is limited to the range [1; 9999].

datetime.strftime() is limited to year >= 1000 (instead of year >= 1900) because it cannot set accept2dyear=0 temporary (it is no thread safe). We might fix it, but it is complex and not really needed. The correct fix is just to remove accept2dyear (and consider that accept2dyear=0), which cannot be done before Python 3.3.

Anyway, the situation is much better in Python 3.2 than Python 3.1, and I consider that it's enough. Let's close the issue.
History
Date User Action Args
2013-10-04 14:02:48r.david.murraylinkissue19162 superseder
2011-01-08 16:40:31hayposetstatus: open -> closed

messages: + msg125792
resolution: fixed
nosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
2011-01-08 03:39:00hayposetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125748
2011-01-08 02:01:32hayposetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125743
2011-01-08 01:49:03belopolskysetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125742
2011-01-08 01:36:50hayposetfiles: + strftime_1_9999.patch
nosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125741
2011-01-08 01:34:59belopolskysetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125740
2011-01-08 01:08:57belopolskysetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125738
2011-01-08 00:26:18hayposetfiles: + datetime_strftime_nolimit.diff
nosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125736
2011-01-07 22:59:33belopolskysetfiles: + issue1777412.diff
nosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
messages: + msg125725

dependencies: + Functions in time module should support year < 1900 when accept2dyear = 0
stage: patch review -> commit review
2011-01-07 20:39:46belopolskylinkissue10827 superseder
2011-01-05 23:20:30belopolskysetnosy: loewis, georg.brandl, davidfraser, belopolsky, benno, haypo, giampaolo.rodola, eric.araujo, kiorky
title: Python's strftime dislikes years before 1900 -> datetime.strftime dislikes years before 1900
2011-01-05 23:19:54belopolskysetnosy: + georg.brandl
messages: + msg125478
2010-10-10 10:08:43loewissetmessages: + msg118331
2010-10-10 09:46:18kiorkysetmessages: + msg118328
2010-10-08 18:39:52belopolskysetmessages: + msg118212
2010-10-08 04:37:26kiorkysetfiles: + strftime-pre-1900.patch

messages: + msg118163
2010-07-19 18:19:13belopolskysetdependencies: + Add pure Python implementation of datetime module to CPython
superseder: Add pure Python implementation of datetime module to CPython ->
2010-07-19 18:19:00belopolskysetsuperseder: Add pure Python implementation of datetime module to CPython
messages: + msg110792
stage: patch review
2010-06-06 00:22:48belopolskysetversions: + Python 3.2
nosy: + belopolsky

messages: + msg107167

assignee: belopolsky
2010-05-31 12:16:20eric.araujosetnosy: + eric.araujo
2010-05-31 10:36:16giampaolo.rodolasetnosy: + giampaolo.rodola
2010-05-20 20:36:46skip.montanarosetnosy: - skip.montanaro
2010-02-26 16:36:35kiorkysetmessages: + msg100165
2010-02-26 16:36:02kiorkysetnosy: + kiorky
messages: + msg100163
2008-11-11 04:11:28hayposetmessages: + msg75731
2008-11-11 04:10:14hayposetmessages: - msg75729
2008-11-11 04:10:07hayposetmessages: + msg75729
2008-11-11 03:50:08hayposetnosy: + haypo
messages: + msg75727
2008-05-10 21:04:51skip.montanarosetmessages: + msg66585
2008-05-10 20:41:48davidfrasersetmessages: + msg66584
2008-05-10 16:45:27skip.montanarosetnosy: + skip.montanaro
messages: + msg66541
2008-05-10 15:35:25davidfrasersetfiles: + strftime-pre-1900.patch
nosy: + davidfraser
messages: + msg66535
keywords: + patch
2007-08-20 03:36:14bennocreate