GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `datetime.strftime("%Y")` is not padding correctly · Issue #120713 · python/cpython

datetime.strftime("%Y") is not padding correctly #120713

New issue
Copy link
New issue
Copy link
Closed
Closed
datetime.strftime("%Y") is not padding correctly#120713
Copy link
Labels
type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@martinvuyk
martinvuyk
opened on Jun 18, 2024
Issue body actions

Bug report

Bug description:

docs say:

%Y

Year with century as a decimal number.

0001, 0002, …, 2013, 2014, …, 9998, 9999

but this is what is happening

from datetime import datetime

print(datetime(9, 6, 7).strftime("%Y-%m-%d")) # 9-06-07
print(datetime(99, 6, 7).strftime("%Y-%m-%d")) # 99-06-07
print(datetime(999, 6, 7).strftime("%Y-%m-%d")) # 999-06-07

CPython versions tested on:

3.10

Operating systems tested on:

No response

Linked PRs

  • gh-120713: normalize year with century for datetime.strftime #120820
  • [3.13] gh-120713: Normalize year with century for datetime.strftime (GH-120820) #121144
  • [3.12] gh-120713: Normalize year with century for datetime.strftime (GH-120820) #121145
  • [3.13] Revert "[3.13] gh-120713: Normalize year with century for datetime.strftime (GH-120820) (GH-121144)" #122408
  • [3.12] Revert "[3.12] gh-120713: Normalize year with century for datetime.strftime (GH-120820) (GH-121145)" #122409
  • gh-120713: Make _Py_NORMALIZE_CENTURY private #135933
  • [3.14] gh-120713: Make _Py_NORMALIZE_CENTURY private (GH-135933) #136387

Activity

Next
  1. martinvuyk
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Jun 18, 2024
  2. Eclips4
    added this to Date and time issues 🕰️on Jun 18, 2024
  3. blhsing commented on Jun 19, 2024

    @blhsing
    blhsing
    on Jun 19, 2024
    Contributor
    More actions

    Reproducible on 3.10 but not on 3.11+.

  4. serhiy-storchaka commented on Jun 19, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 19, 2024
    Member
    More actions

    cc @pganssle

    I suppose that it works in such way since Python 3.0 (I tested in 3.3). 2.7 does not support years before 1900.

    You can use %4Y to always get 4-digit year. I wonder whether this is a documentation issue or the output is platform depending.

    Reacted by martinvuyk
  5. blhsing commented on Jun 19, 2024

    @blhsing
    blhsing
    on Jun 19, 2024
    Contributor
    More actions

    I wonder whether this is a documentation issue or the output is platform depending.

    Ah, so the issue is platform-dependent. When I reproduced the OP's issue in 3.10 I was doing it in Linux, while in Windows I tested the code in 3.11 and 3.13 and the issue was not reproduced. Now I realized that this is just a result of datetime.strftime being a thin wrapper over the platform's strftime in the C library:

    According to the doc:

    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.

    Reacted by martinvuyk
  6. serhiy-storchaka commented on Jun 20, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 20, 2024
    Member
    More actions

    The limitation for year >= 1000 was removed in bpo-11930 (gh-56139). But there were various problems with the newly added test test_strftime_y2k, it required several corrections.

    For now, we cannot guarantee the result for %Y (and %G) with year < 1000. It is especially bad since strptime() requires the year to be 4 digits.

  7. blhsing
    added 2 commits that reference this issue on Jun 21, 2024

    pythongh-120713: normalize year with century for datetime.strftime

    9022177

    pythongh-120713: fixed pyconfig.h.in

    48affbd
  8. blhsing commented on Jun 21, 2024

    @blhsing
    blhsing
    on Jun 21, 2024
    Contributor
    More actions

    Since datetime.strftime already uses a wrapper function to handle format specifiers not conforming to the C strftime, I think a reasonable fix would be to add the translation of %Y to %4Y there as needed by the platform to make the function portable.

  9. serhiy-storchaka commented on Jun 21, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 21, 2024
    Member
    More actions

    Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.

  10. blhsing commented on Jun 21, 2024

    @blhsing
    blhsing
    on Jun 21, 2024
    Contributor
    More actions

    Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.

    With PR #120820 I've made sure that the translation is only used when explicitly supported by the platform so that it is at least an improvement and not a regression in any case. I did just revert my changes to the unit test to allow an outlier platform to pass the test.

  11. blhsing
    added 2 commits that reference this issue on Jun 24, 2024

    pythongh-120713: format "%Y" with "%4d" using sprintf instead of repl…

    6ca887e

    pythongh-120713: test that a 0-padded year with century is guaranteed

    a9623c4
  12. blhsing commented on Jun 24, 2024

    @blhsing
    blhsing
    on Jun 24, 2024
    Contributor
    More actions

    Yes, but the problem is that %4Y is a glibc extension. There are platforms that return non-4-digit number and do not support %4Y. If we are going to guarantee 4 digits, the workaround may be much more complex.

    On second thought, guaranteeing 4 digits is actually not complex since we can simply format the year with "%04ld" using sprintf, which works on all platforms.

    I've updated the PR accordingly so that a 4-digit year with century can now be guaranteed.

    Reacted by martinvuyk
  13. blhsing
    added a commit that references this issue on Jun 24, 2024

    pythongh-120713: revised detection logics in Python

    2fc1c6a
  14. 50 remaining items

  15. blhsing commented on Sep 4, 2024

    @blhsing
    blhsing
    on Sep 4, 2024
    Contributor
    More actions

    I'm not sure why but we are seeing failures on JIT for the test_strftime_y2k on emulated Linux. Is it because emulated Linux have (yet) another weird case of glibc?

    Thanks for the heads-up. It is weird indeed that this can happen since according to the build log the configure script did detect that the platform would not 0-pad a century so the handler for %Y would format the year itself with snprintf using the "%04ld" format string.

    Since this happens only on aarch64 perhaps there is indeed some peculiarity of snprintf in the glibc of that platform.

    Will try debugging this on a Mac later.

    Also, the reason we reverted the commits on 3.12 and 3.13 was because it was more of a feature than a bugfix?

    It's a bug fix but was found to be incomplete, due to issue #122272.

  16. serhiy-storchaka commented on Sep 4, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Sep 4, 2024
    Member
    More actions

    Please open a new issue and provide more details.

  17. picnixz commented on Sep 4, 2024

    @picnixz
    picnixz
    on Sep 4, 2024
    Member
    More actions

    See #123681.

    Reacted by Serhiy Storchaka
  18. encukou
    added a commit that references this issue on Jun 25, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private

    fc68cbc
  19. encukou
    added a commit that references this issue on Jul 7, 2025

    gh-120713: Make _Py_NORMALIZE_CENTURY private (GH-135933)

    fb170cf
  20. miss-islington
    added a commit that references this issue on Jul 7, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    06720fd
  21. hugovk
    added a commit that references this issue on Jul 8, 2025

    [3.14] gh-120713: Make _Py_NORMALIZE_CENTURY private (GH-135933) (#13…

    376e037
  22. AndPuQing
    added a commit that references this issue on Jul 11, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    8f7d86d
  23. Pranjal095
    added a commit that references this issue on Jul 12, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    dc6ed76
  24. picnixz
    added a commit that references this issue on Jul 13, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    0d1a69a
  25. taegyunkim
    added a commit that references this issue on Aug 4, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    1ea68b8
  26. Agent-Hellboy
    added a commit that references this issue on Aug 19, 2025

    pythongh-120713: Make _Py_NORMALIZE_CENTURY private (pythonGH-135933)

    79668d7
  27. Nemris
    added a commit that references this issue on Oct 18, 2025

    Work around Python strftime bug

    59afd86
  28. nixos-cuda-channel-updater
    added a commit that references this issue on Jul 18, 2026

    icloudpd: build with python313

    0fde69f
  29. RaymondMin72
    added a commit that references this issue on Oct 3, 2026

    fix: zero-pad early creation years on the detail page

    d37a794
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    • Date and time issues 🕰️
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402520 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.