Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions deepdiff/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,10 @@ def datetime_normalize(
datetime.timezone, "BaseTzInfo"
] = datetime.timezone.utc,
) -> Any:
# A plain date has no time component, so truncation does not apply to it.
has_time = not (isinstance(obj, datetime.date) and not isinstance(obj, datetime.datetime))
if truncate_datetime and has_time:
# Only datetime and time objects carry truncatable time fields. A plain
# date has no time component, and other types (e.g. timedelta) do not
# support .replace() with time fields, so truncation skips them.
if truncate_datetime and isinstance(obj, (datetime.datetime, datetime.time)):
if truncate_datetime == 'second':
obj = obj.replace(microsecond=0)
elif truncate_datetime == 'minute':
Expand Down
23 changes: 22 additions & 1 deletion tests/test_diff_datetime.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import pytz
from datetime import date, datetime, time, timezone
from datetime import date, datetime, time, timedelta, timezone
from deepdiff import DeepDiff


Expand Down Expand Up @@ -123,3 +124,23 @@ def test_datetime_within_array_with_timezone_diff(self):
assert not DeepDiff(d1, d2)
assert not DeepDiff(d1, d2, ignore_order=True)
assert not DeepDiff(d1, d2, truncate_datetime='second')

def test_truncate_datetime_with_timedelta(self):
"""truncate_datetime must not crash on timedelta (no .replace())."""
for truncate_datetime in ('second', 'minute', 'hour', 'day'):
d1 = {"a": timedelta(days=1)}
d2 = {"a": timedelta(days=1)}
assert not DeepDiff(d1, d2, truncate_datetime=truncate_datetime)
d2 = {"a": timedelta(days=2)}
assert DeepDiff(d1, d2, truncate_datetime=truncate_datetime)

def test_truncate_datetime_with_np_datetime64(self):
"""truncate_datetime must not crash on np.datetime64 (no .replace())."""
np = pytest.importorskip("numpy")
from deepdiff import DeepHash
for truncate_datetime in ('second', 'minute', 'hour', 'day'):
h1 = DeepHash(np.datetime64('2020-05-17'), truncate_datetime=truncate_datetime)
h2 = DeepHash(np.datetime64('2020-05-17'), truncate_datetime=truncate_datetime)
assert h1 == h2
h3 = DeepHash(np.datetime64('2020-05-18'), truncate_datetime=truncate_datetime)
assert h1 != h3
Loading