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

time.strptime too strict? should it assume current year? #46480

Closed
gpshead opened this issue Mar 3, 2008 · 5 comments
Closed

time.strptime too strict? should it assume current year? #46480

gpshead opened this issue Mar 3, 2008 · 5 comments
Assignees
Labels
easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@gpshead
Copy link
Member

gpshead commented Mar 3, 2008

BPO 2227
Nosy @brettcannon, @gpshead, @tebeka
Files
  • _strptime.diff: _strptime.py path to default to current year
  • test_strptime.diff: adaption of the corresponding test case
  • 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/brettcannon'
    closed_at = <Date 2009-04-02.05:42:12.207>
    created_at = <Date 2008-03-03.21:41:25.413>
    labels = ['easy', 'type-bug', 'library']
    title = 'time.strptime too strict?  should it assume current year?'
    updated_at = <Date 2009-04-02.05:42:12.205>
    user = 'https://github.com/gpshead'

    bugs.python.org fields:

    activity = <Date 2009-04-02.05:42:12.205>
    actor = 'brett.cannon'
    assignee = 'brett.cannon'
    closed = True
    closed_date = <Date 2009-04-02.05:42:12.207>
    closer = 'brett.cannon'
    components = ['Library (Lib)']
    creation = <Date 2008-03-03.21:41:25.413>
    creator = 'gregory.p.smith'
    dependencies = []
    files = ['9788', '9800']
    hgrepos = []
    issue_num = 2227
    keywords = ['patch', 'easy']
    message_count = 5.0
    messages = ['63236', '63239', '64192', '64227', '85169']
    nosy_count = 4.0
    nosy_names = ['brett.cannon', 'gregory.p.smith', 'tebeka', 'schuppenies']
    pr_nums = []
    priority = 'low'
    resolution = 'rejected'
    stage = 'patch review'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue2227'
    versions = ['Python 2.6', 'Python 2.5', 'Python 3.0']

    @gpshead
    Copy link
    Member Author

    gpshead commented Mar 3, 2008

    Some common python utilities had problems on Feb 29 this year when
    parsing dates using format strings that did not include a year in them.

    >>> time.strptime('Feb 29', '%b %d')
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "/usr/lib/python2.4/_strptime.py", line 425, in strptime
        julian = datetime_date(year, month, day).toordinal() - \
    ValueError: day is out of range for month

    This is apparently because python assumes the year is 1900 unless it
    explicitly parses another year out of the string.

    Applications can work around this by always adding a year and a %Y to
    the string they are parsing.

    But not all date manipulating applications care about years. In this
    case the application was fail2ban, bug report and patches to it here:

    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468382

    Should the year default to 1900 (the equivalent of what the much more
    forgiving C API does by leaving struct tm tm_year = 0) or should this
    error be raised? If the answer is yes, works as is this is easy and
    just turns into us adding a note in the documentation to mention the
    behavior.

    I do believe this was a valid bug in fail2ban as assuming the current
    year for date parsing is a bad idea and will do the wrong thing when
    parsing across a year change.

    Python's strptime is much more strict than C strptime (glibc's C
    strptime is happy to return tm_mon 2 tm_mday 31. Its range checking is
    minimal.

    here's a C test case to play with its behavior:

    #include <assert.h>
    #include <stdio.h>
    #include <time.h>
    int main(int argc, char *argv[]) {
      unsigned long ret, parsed;
      assert(argc == 2);
      struct tm tm = { 0 };
      ret = strptime(argv[1], "%b %d", &tm);
      parsed = ret - (unsigned long)(argv[1]);
      printf("ret 0x%x  parsed %d  tm_mon %d  tm_mday %d  tm_year %d\n",
             ret, parsed,
             tm.tm_mon, tm.tm_mday, tm.tm_year);
    }

    % ./foo 'Feb 28'
    ret 0xffffda8a parsed 6 tm_mon 1 tm_mday 28 tm_year 0
    % ./foo 'Feb 29'
    ret 0xffffda8a parsed 6 tm_mon 1 tm_mday 29 tm_year 0
    % ./foo 'Feb 31'
    ret 0xffffda8a parsed 6 tm_mon 1 tm_mday 31 tm_year 0
    % ./foo 'Feb 32'
    ret 0x0 parsed 9596 tm_mon 1 tm_mday 0 tm_year 0

    @gpshead gpshead added stdlib Python modules in the Lib dir easy type-bug An unexpected behavior, bug, or error labels Mar 3, 2008
    @brettcannon
    Copy link
    Member

    The documentation already mentions that the default values when
    information left out is (1900, 1, 1, 0, 0, 0, 0, 1, -1) so the docs are
    already clear. If you want to generate a patch to make the default year
    be this year I would be willing to review it and consider applying it. I
    doubt very much code would break because of this.

    @tebeka
    Copy link
    Mannequin

    tebeka mannequin commented Mar 20, 2008

    Here is a patch, hope it'll make it to 2.6

    @schuppenies
    Copy link
    Mannequin

    schuppenies mannequin commented Mar 21, 2008

    Applying the _strptime.diff patch broke the _strptime
    test("test_defaults"). Once you change the year, you also have to adapt
    the day of week, as this becomes dynamic, too. The rest remains the
    same, though. I attached a patch to this test which tests for the
    new-years day of the current year instead of 1900, but I feel like
    changing the semantic of the default value is no minor change. Also, I
    am not sure what the documentation should say then.

    @brettcannon brettcannon self-assigned this Mar 21, 2008
    @brettcannon
    Copy link
    Member

    After having thought about this I have decided I am going to stick with
    the current semantics. Having the year change underneath code based
    solely on when it executes will cause more problems than it will solve.

    @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
    easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants