datetime serialization/deserialization broken
shyamd opened this issue · 3 comments
datetime objects with time zone info break the serializatin because __str__
doesn't output in the format that monty expects. Example:
datetime.datetime(2018, 12, 19, 21, 45, 41, 99000, tzinfo=datetime.timezone.utc).__str__()
yields
"2018-12-19 21:45:41.099000+00:00"
When deserializing, this causes monty to throw an error because the two datetime formatting strings it tries are:
- "%Y-%m-%d %H:%M:%S.%f"
- "%Y-%m-%d %H:%M:%S"
resulting in value error like this from within strptime
:
ValueError: unconverted data remains: .967000+00:00
We could just add the timezone format, or just use a formatting string when outputting from datetime to a string during serialization. There are also generic datetime parsing libraries like dateutil
I could confirm this issue for strptime
with time zone info, materialsproject/pymatgen#3705 (comment).
import datetime
start_time_old = datetime.datetime.utcnow() # 2024-03-25 08:46:23.748342
start_time_new = datetime.datetime.now(datetime.UTC) # 2024-03-25 08:46:23.748472+00:00
print(start_time_old, start_time_new)
dt = datetime.datetime.strptime(
str(start_time_old), "%Y-%m-%d %H:%M:%S.%f"
)
print(dt)
dt = datetime.datetime.strptime(
str(start_time_new), "%Y-%m-%d %H:%M:%S.%f"
)
print(dt)
Which raises:
Traceback (most recent call last):
File "/Users/yang/developer/test/test.py", line 16, in <module>
dt = datetime.datetime.strptime(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.12/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/_strptime.py", line 554, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.12/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/_strptime.py", line 336, in _strptime
raise ValueError("unconverted data remains: %s" %
ValueError: unconverted data remains: +00:00
I don't have time to fix this. But feel free to submit a PR.
I'm currently working on this, here I enclose a code snippet to recreate this issue from monty
's side (for my own record):
import json
import datetime
from monty.json import MontyEncoder, MontyDecoder
# created_at = datetime.datetime.utcnow() # deprecated API
created_at = datetime.datetime.now(tz=datetime.timezone.utc)
data = json.loads(json.dumps(created_at, cls=MontyEncoder))
created_at = MontyDecoder().process_decoded(data)
Gives:
Traceback (most recent call last):
File "/home/yang/monty/monty/json.py", line 750, in process_decoded
dt = datetime.datetime.strptime(
File "/usr/lib/python3.10/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/lib/python3.10/_strptime.py", line 352, in _strptime
raise ValueError("unconverted data remains: %s" %
ValueError: unconverted data remains: +00:00
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/yang/monty/recreate.py", line 10, in <module>
created_at = MontyDecoder().process_decoded(data)
File "/home/yang/monty/monty/json.py", line 754, in process_decoded
dt = datetime.datetime.strptime(
File "/usr/lib/python3.10/_strptime.py", line 568, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/lib/python3.10/_strptime.py", line 352, in _strptime
raise ValueError("unconverted data remains: %s" %
ValueError: unconverted data remains: .914911+00:00