Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python ValueError: ':' is a bad directive in format '%Y-%m-%d%X%:z'

I'm attempting to parse HTML time strings in Python:

from datetime import datetime

input = "2025-03-24T07:01:53+00:00"
output = datetime.strptime(input, "%Y-%m-%d%X%:z")
print(output)

Running this with Python 3.13 returns the following error:

Traceback (most recent call last):
  File "/Users/dread_pirate_roberts/html_time_converter/main.py", line 69, in <module>
    output = datetime.strptime(input, "%Y-%m-%d%X%:z")
  File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/_strptime.py", line 674, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
                                    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/_strptime.py", line 445, in _strptime
    raise ValueError("'%s' is a bad directive in format '%s'" %
                        (bad_directive, format)) from None
ValueError: ':' is a bad directive in format '%Y-%m-%d%X%:z'

This doesn't make sense to me because %:z was added in Python 3.12.

Edit: I discovered that my code actually has 2 bugs. For one, the format string should include a T. Also, InSync's answer, so the code should be:

from datetime import datetime

input = "2025-03-24T07:01:53+00:00"
output = datetime.strptime(input, "%Y-%m-%dT%X%z")
print(output)
like image 933
The-Coder-Who-Knew-Too-Little Avatar asked Nov 17 '25 07:11

The-Coder-Who-Knew-Too-Little


1 Answers

This is a known CPython bug.

For now (3.13), %:z only works in .strftime():

>>> import datetime
>>> d = datetime.datetime.now(tz = datetime.UTC)
>>> d
datetime.datetime(2025, 1, 1, 1, 1, 1, 111111, tzinfo=datetime.timezone.utc)
>>> d.strftime('%z')
'+0000'
>>> d.strftime('%:z')
'+00:00'

It should also be noted that %z already parses +00:00 and similar inputs:

>>> datetime.datetime.strptime('+00:30', '%z')
datetime.datetime(1900, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=1800)))
like image 128
InSync Avatar answered Nov 19 '25 22:11

InSync