Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datetime.strftime dislikes years before 1900 #45329

Closed
benno mannequin opened this issue Aug 20, 2007 · 26 comments
Closed

datetime.strftime dislikes years before 1900 #45329

benno mannequin opened this issue Aug 20, 2007 · 26 comments
Assignees
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@benno
Copy link
Mannequin

benno mannequin commented Aug 20, 2007

BPO 1777412
Nosy @loewis, @birkenfeld, @abalkin, @vstinner, @giampaolo, @merwok
Dependencies
  • bpo-7989: Add pure Python implementation of datetime module to CPython
  • bpo-10827: Functions in time module should support year < 1900 when accept2dyear = 0
  • Files
  • strftime-pre-1900.patch: patch to use strftime directly from datetime instead of going through the time module, and remove the pre-1900 restriction
  • strftime-pre-1900.patch
  • issue1777412.diff
  • datetime_strftime_nolimit.diff
  • strftime_1_9999.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/abalkin'
    closed_at = <Date 2011-01-08.16:40:31.480>
    created_at = <Date 2007-08-20.03:36:14.000>
    labels = ['type-feature', 'library']
    title = 'datetime.strftime dislikes years before 1900'
    updated_at = <Date 2011-01-08.16:40:31.478>
    user = 'https://bugs.python.org/benno'

    bugs.python.org fields:

    activity = <Date 2011-01-08.16:40:31.478>
    actor = 'vstinner'
    assignee = 'belopolsky'
    closed = True
    closed_date = <Date 2011-01-08.16:40:31.480>
    closer = 'vstinner'
    components = ['Library (Lib)']
    creation = <Date 2007-08-20.03:36:14.000>
    creator = 'benno'
    dependencies = ['7989', '10827']
    files = ['10253', '19157', '20307', '20309', '20310']
    hgrepos = []
    issue_num = 1777412
    keywords = ['patch']
    message_count = 26.0
    messages = ['55156', '55157', '66535', '66541', '66584', '66585', '75727', '75731', '100163', '100165', '107167', '110792', '118163', '118212', '118328', '118331', '125478', '125725', '125736', '125738', '125740', '125741', '125742', '125743', '125748', '125792']
    nosy_count = 9.0
    nosy_names = ['loewis', 'georg.brandl', 'davidfraser', 'belopolsky', 'benno', 'vstinner', 'giampaolo.rodola', 'eric.araujo', 'kiorky']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'commit review'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue1777412'
    versions = ['Python 3.2']

    @benno
    Copy link
    Mannequin Author

    benno mannequin commented Aug 20, 2007

    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?

    @benno benno mannequin added stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Aug 20, 2007
    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Aug 21, 2007

    This is not a bug report, but a feature request. Python works correctly as-is.

    @davidfraser
    Copy link
    Mannequin

    davidfraser mannequin commented May 10, 2008

    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...

    @smontanaro
    Copy link
    Contributor

    Which version of Python are you using? I could have sworn we just fixed
    this problem in CVS a couple weeks ago.

    @davidfraser
    Copy link
    Mannequin

    davidfraser mannequin commented May 10, 2008

    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

    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...

    @smontanaro
    Copy link
    Contributor

    Ah, I remember now. It was a special case for xmlrpclib to allow
    its Date objects to operate before 1900.

    @vstinner
    Copy link
    Member

    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.

    @vstinner
    Copy link
    Member

    See also issue bpo-3173.

    @kiorky
    Copy link
    Mannequin

    kiorky mannequin commented Feb 26, 2010

    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.

    @kiorky
    Copy link
    Mannequin

    kiorky mannequin commented Feb 26, 2010

    And forgotten to say that it worked for me for py26 and py24.

    @abalkin
    Copy link
    Member

    abalkin commented Jun 6, 2010

    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.

    @abalkin
    Copy link
    Member

    abalkin commented Jul 19, 2010

    Adding bpo-7989 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 bpo-7989 would mean that year < 1900 would have to be disabled for pure python implementation tests.

    @kiorky
    Copy link
    Mannequin

    kiorky mannequin commented Oct 8, 2010

    This patch doesnt apply anymore on py26.
    Joining an updated patch.

    @abalkin
    Copy link
    Member

    abalkin commented Oct 8, 2010

    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.

    @kiorky
    Copy link
    Mannequin

    kiorky mannequin commented Oct 10, 2010

    We must not have the same point of view about new features and bugfixes...

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Oct 10, 2010

    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.

    @abalkin
    Copy link
    Member

    abalkin commented Jan 5, 2011

    I would like to push this for 3.2. Recent discussions at bpo-10827 and on python-dev seem to favor removal of arbitrary limits on year range.

    @abalkin abalkin changed the title Python's strftime dislikes years before 1900 datetime.strftime dislikes years before 1900 Jan 5, 2011
    @abalkin abalkin changed the title Python's strftime dislikes years before 1900 datetime.strftime dislikes years before 1900 Jan 5, 2011
    @abalkin
    Copy link
    Member

    abalkin commented Jan 7, 2011

    After r87829 (see bpo-10827), 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.

    @vstinner
    Copy link
    Member

    vstinner commented Jan 8, 2011

    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.

    @abalkin
    Copy link
    Member

    abalkin commented Jan 8, 2011

    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).

    @abalkin
    Copy link
    Member

    abalkin commented Jan 8, 2011

    --
    --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 ^^^

    @vstinner
    Copy link
    Member

    vstinner commented Jan 8, 2011

    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.

    @abalkin
    Copy link
    Member

    abalkin commented Jan 8, 2011

    I like strftime_1_9999.patch, but it really belongs to bpo-10827. Please leave a note there once you commit and mention the issue in commit log.

    @vstinner
    Copy link
    Member

    vstinner commented Jan 8, 2011

    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.

    @vstinner
    Copy link
    Member

    vstinner commented Jan 8, 2011

    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 bpo-10864) limits year to [1; 9999] on Solaris.

    @vstinner
    Copy link
    Member

    vstinner commented Jan 8, 2011

    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.

    @vstinner vstinner closed this as completed Jan 8, 2011
    @vstinner vstinner closed this as completed Jan 8, 2011
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants