Skip to content

Support %:z in datetime.datetime.strptime #121237

Closed

Description

@za3k

Bug report

Bug description:

https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes documents "strftime() and strptime() Format Codes". It mentions the new %:z variant of %z, introduced in Python 3.12

>>> datetime.datetime.strptime("2023-07-17T13:58:49-07:00", "%Y-%m-%dT%H:%M:%S%z")
datetime.datetime(2023, 7, 17, 13, 58, 49, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=61200)))
>>> datetime.datetime.strptime("2023-07-17T13:58:49-07:00", "%Y-%m-%dT%H:%M:%S%:z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.12/_strptime.py", line 554, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/_strptime.py", line 325, in _strptime
    raise ValueError("'%s' is a bad directive in format '%s'" %
ValueError: ':' is a bad directive in format '%Y-%m-%dT%H:%M:%S%:z'

But passing "%:z" to strptime raises an error. This is a bug because strptime and strftime should have the same format codes, according to the docs.

Since %z already parses this format when passed to strptime, I think %:z should just do the same thing.

Workaround: Change %:z to %z in your format string for strptime.

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Jul 1, 2024
  2. nineteendo commented on Jul 1, 2024

    @nineteendo
    Contributor

    Wouldn't %:z have to reject -0400?

  3. za3k commented on Jul 1, 2024

    @za3k
    Author

    Reasonable question. Shouldn't %z reject -04:00? It doesn't, currently.

    Both should parse the alternative format, or neither, for the sake of consistency.

    The current behavior for %z is old (predates %:z from 3.12). I would argue for both to avoid breaking backwards compatibility.

  4. nineteendo commented on Jul 1, 2024

    @nineteendo
    Contributor

    In my view : is optional for %z, so it's not used in strftime(), while it's required in %:z.
    If we enforce this, this actually allows something new instead of an alternative way to do it:

    There should be one-- and preferably only one --obvious way to do it.

    This should probably be labeled as a new feature.

  5. za3k commented on Jul 1, 2024

    @za3k
    Author

    I think either implementation would be an improvement. I raise no objection :)

  6. nineteendo commented on Jul 1, 2024

    @nineteendo
    Contributor

    @Eclips4 can you add the feature label?

  7. LucasEsposito commented on Jul 20, 2024

    @LucasEsposito
    Contributor

    I'll be taking care of this one

    As dicussed, we need to have consistency across strptime and strftime, while keeping backwards compatibility.

    • %z and %:z work as expected in strftime, so no need to change anything there.
    • %z does what it should in strptime, while in addition allowing %:z-formatted strings too (see third comment). We should keep this behavior for backwards compatibility.
    • %:z fails in strptime. We should allow %:z there and make it parse only %:z-formatted strings.
  8. added 2 commits that reference this issue on Jul 22, 2024
  9. LucasEsposito commented on Jul 22, 2024

    @LucasEsposito
    Contributor

    I added a PR addressing the issue: #122142

  10. added a commit that references this issue on Jul 23, 2024
  11. added
    stdlibStandard Library Python modules in the Lib/ directory
    type-featureA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or error
    on Jun 29, 2025
  12. changed the title [-]Let strptime accept %:z[/-] [+]Support `%:z` in `datetime.datetime.strptime`[/+] on Jun 29, 2025
  13. StanFromIreland commented on Jun 29, 2025

    @StanFromIreland
    Member

    This was implemented for strftime without consideration for strptime in 023c51d 3 years ago. I would consider this a documentation bug, since it does imply it should be available on strptime also, but implementing it is a feature now.

  14. added 3 commits that reference this issue on Jul 21, 2025
  15. bn-jbischko commented on Sep 13, 2025

    @bn-jbischko

    Any reason why strptime doesn't return a datetime object with timezone, when %Z is used, either?

    $ python
    Python 3.13.5 (main, Jun 11 2025, 15:36:57) [GCC 14.3.0] on linux
    >>> from datetime import datetime
    
    >>> datetime.strptime("20250913-CEST1251", "%Y%m%d-%Z%H%M")
    datetime.datetime(2025, 9, 13, 12, 51)
    >>> datetime.strptime("20250913-UTC1251", "%Y%m%d-%Z%H%M")
    datetime.datetime(2025, 9, 13, 12, 51)
    >>> datetime.strptime("20250913-1251", "%Y%m%d-%H%M")
    datetime.datetime(2025, 9, 13, 12, 51)

    Edit: Nevermind, see #66571

  16. added a commit that references this issue on Sep 19, 2025
  17. pganssle commented on Sep 19, 2025

    @pganssle
    Member

    This has now been implemented and merged in #136961

  18. Iris-Hinrichs commented on Sep 29, 2026

    @Iris-Hinrichs

    Although this issue has been closed and the changes seem to be implemented and merged into main I still get the same error as on top of this discussion when using python3.14 (cpython implementation). In which python release should this change be available?
    Thanks for any reply on this comment!

  19. StanFromIreland commented on Sep 29, 2026

    @StanFromIreland
    Member

    It was added to Python 3.15, which is to be released in two days.

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

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions