Skip to content

datetime.strftime with %Y no longer outputs leading zeros #76376

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

Closed
davechallis mannequin opened this issue Dec 1, 2017 · 6 comments
Closed

datetime.strftime with %Y no longer outputs leading zeros #76376

davechallis mannequin opened this issue Dec 1, 2017 · 6 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@davechallis
Copy link
Mannequin

davechallis mannequin commented Dec 1, 2017

BPO 32195
Nosy @ronaldoussoren, @abalkin, @ned-deily, @serhiy-storchaka, @davechallis
Superseder
  • bpo-13305: datetime.strftime("%Y") not consistent for years < 1000
  • 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 = None
    closed_at = <Date 2017-12-01.23:01:16.411>
    created_at = <Date 2017-12-01.14:39:29.365>
    labels = ['type-bug', 'library']
    title = 'datetime.strftime with %Y no longer outputs leading zeros'
    updated_at = <Date 2017-12-01.23:01:16.410>
    user = 'https://github.com/davechallis'

    bugs.python.org fields:

    activity = <Date 2017-12-01.23:01:16.410>
    actor = 'ned.deily'
    assignee = 'none'
    closed = True
    closed_date = <Date 2017-12-01.23:01:16.411>
    closer = 'ned.deily'
    components = ['Library (Lib)']
    creation = <Date 2017-12-01.14:39:29.365>
    creator = 'davechallis'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 32195
    keywords = []
    message_count = 6.0
    messages = ['307389', '307398', '307401', '307413', '307415', '307416']
    nosy_count = 5.0
    nosy_names = ['ronaldoussoren', 'belopolsky', 'ned.deily', 'serhiy.storchaka', 'davechallis']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = 'resolved'
    status = 'closed'
    superseder = '13305'
    type = 'behavior'
    url = 'https://bugs.python.org/issue32195'
    versions = ['Python 3.6']

    @davechallis
    Copy link
    Mannequin Author

    davechallis mannequin commented Dec 1, 2017

    Tested in python 3.6.2:

        >>> import datetime
        >>> datetime.datetime.min.strftime('%Y')
        '1'

    Expected output:

    '0001'
    

    This means that strftime and strptime aren't necessarily symmetric, e.g.:

        >>> datetime.datetime.strptime(datetime.datetime.min.strftime('%Y'), '%Y')
        ValueError: time data '1' does not match format '%Y'

    @davechallis davechallis mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Dec 1, 2017
    @serhiy-storchaka
    Copy link
    Member

    In what version datetime.strftime with %Y did output leading zeros?

    @davechallis
    Copy link
    Mannequin Author

    davechallis mannequin commented Dec 1, 2017

    My mistake, it appears to be related to the OS it's running on rather than the version (I just happened to test with different versions on different OSes).

    On Mac OS X (with 3.6.2):

        >>> import datetime
        >>> datetime.datetime.min.strftime('%Y')
        '0001'

    On Linux (with 3.6.2 again):

        >>> import datetime
        >>> datetime.datetime.min.strftime('%Y')
        '1

    @ned-deily
    Copy link
    Member

    As documented in the Python Library Reference: "The full set of format codes supported varies across platforms, because Python calls the platform C library’s strftime() function, and platform variations are common. To see the full set of format codes supported on your platform, consult the strftime(3) documentation."

    And this appears to be one of those differences, presumably another GNU libc vs BSD one, as I see the same behavior as macOS on the FreeBSD system I have available.

    The Open Group 2008 documentation for the strftime C interface discusses this problem a bit here (http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html):

    "The %Y conversion specification to strftime() was frequently assumed to be a four-digit year, but the ISO C standard does not specify that %Y is restricted to any subset of allowed values from the tm_year field. Similarly, the %C conversion specification was assumed to be a two-digit field and the first part of the output from the %F conversion specification was assumed to be a four-digit field. With tm_year being a signed 32 or more-bit int and with many current implementations supporting 64-bit time_t types in one or more programming environments, these assumptions are clearly wrong.

    POSIX.1-2008 now allows the format specifications %0xC, %0xF, %0xG, and %0xY (where 'x' is a string of decimal digits used to specify printing and scanning of a string of x decimal digits) with leading zero fill characters. Allowing applications to set the field width enables them to agree on the number of digits to be printed and scanned in the ISO 8601:2000 standard expanded representation of a year (for %F, %G, and %Y ) or all but the last two digits of the year (for %C ). This is based on a feature in some versions of GNU libc's strftime(). The GNU version allows specifying space, zero, or no-fill characters in strftime() format strings, but does not allow any flags to be specified in strptime() format strings. These implementations also allow these flags to be specified for any numeric field. POSIX.1-2008 only requires the zero fill flag ( '0' ) and only requires that it be recognized when processing %C, %F, %G, and %Y specifications when a minimum field width is also specified. The '0' flag is the only flag needed to produce and scan the ISO 8601:2000 standard year fields using the extended format forms. POSIX.1-2008 also allows applications to specify the same flag and field width specifiers to be used in both strftime() and strptime() format strings for symmetry. Systems may provide other flag characters and may accept flags in conjunction with conversion specifiers other than %C, %F, %G, and %Y; but portable applications cannot depend on such extensions."

    Experimenting a bit, it seems that the current Linux glibc implementation supports the %0xY extension while the current macOS (and other BSD?) do not.

    Python 3.6.3 (default, Oct  3 2017, 21:16:13)
    [GCC 7.2.0] on linux
    >>> datetime.datetime.min.strftime('%Y')
    '1'
    >>> datetime.datetime.min.strftime('%02Y')
    '01'
    >>> datetime.datetime.min.strftime('%04Y')
    '0001'
    
    Python 3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08)
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    >>> datetime.datetime.min.strftime('%Y')
    '0001'
    >>> datetime.datetime.min.strftime('%02Y')
    '2Y'
    >>> datetime.datetime.min.strftime('%04Y')
    '4Y'

    So I'm afraid there's not much we can do about that without changing Python's policy about using the platform's native implementations of date and time functions.

    Alexander, do you agree?

    @abalkin
    Copy link
    Member

    abalkin commented Dec 1, 2017

    Isn't this a duplicate of bpo-13305?

    @ned-deily
    Copy link
    Member

    Isn't this a duplicate of bpo-13305?

    Looks like it, thanks, though I think the analysis still applies. Closing as duplicate.

    @ned-deily ned-deily removed the invalid label Dec 1, 2017
    @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-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants