Skip to content

Commit 0d17101

Browse files
committed
adding default timezone
1 parent 8b2aa9c commit 0d17101

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

deepdiff/deephash.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#!/usr/bin/env python
2-
import inspect
2+
import pytz
33
import logging
44
import datetime
5+
from typing import Union
56
from collections.abc import Iterable, MutableMapping
67
from collections import defaultdict
78
from hashlib import sha1, sha256
@@ -14,7 +15,6 @@
1415
number_to_string, datetime_normalize, KEY_TO_VAL_STR,
1516
get_truncate_datetime, dict_, add_root_to_paths, PydanticBaseModel)
1617

17-
from deepdiff.summarize import summarize
1818
from deepdiff.base import Base
1919

2020
try:
@@ -165,6 +165,7 @@ def __init__(self,
165165
encodings=None,
166166
ignore_encoding_errors=False,
167167
ignore_iterable_order=True,
168+
default_timezone:Union[datetime.timezone, datetime.timezone, pytz.tzinfo.BaseTzInfo]=datetime.timezone.utc,
168169
**kwargs):
169170
if kwargs:
170171
raise ValueError(
@@ -173,7 +174,7 @@ def __init__(self,
173174
"exclude_paths, include_paths, exclude_regex_paths, hasher, ignore_repetition, "
174175
"number_format_notation, apply_hash, ignore_type_in_groups, ignore_string_type_changes, "
175176
"ignore_numeric_type_changes, ignore_type_subclasses, ignore_string_case "
176-
"number_to_string_func, ignore_private_variables, parent, use_enum_value "
177+
"number_to_string_func, ignore_private_variables, parent, use_enum_value, default_timezone "
177178
"encodings, ignore_encoding_errors") % ', '.join(kwargs.keys()))
178179
if isinstance(hashes, MutableMapping):
179180
self.hashes = hashes
@@ -190,6 +191,7 @@ def __init__(self,
190191
self.hasher = default_hasher if hasher is None else hasher
191192
self.hashes[UNPROCESSED_KEY] = []
192193
self.use_enum_value = use_enum_value
194+
self.default_timezone = default_timezone
193195

194196
self.significant_digits = self.get_significant_digits(significant_digits, ignore_numeric_type_changes)
195197
self.truncate_datetime = get_truncate_datetime(truncate_datetime)
@@ -317,6 +319,7 @@ def __repr__(self):
317319
"""
318320
Hide the counts since it will be confusing to see them when they are hidden everywhere else.
319321
"""
322+
from deepdiff.summarize import summarize
320323
return summarize(self._get_objects_to_hashes_dict(extract_index=0), max_length=500)
321324

322325
def __str__(self):
@@ -349,6 +352,7 @@ def _prep_obj(self, obj, parent, parents_ids=EMPTY_FROZENSET, is_namedtuple=Fals
349352
if hasattr(obj, "__slots__"):
350353
obj_to_dict_strategies.append(lambda o: {i: getattr(o, i) for i in o.__slots__})
351354
else:
355+
import inspect
352356
obj_to_dict_strategies.append(lambda o: dict(inspect.getmembers(o, lambda m: not inspect.isroutine(m))))
353357

354358
for get_dict in obj_to_dict_strategies:
@@ -478,7 +482,7 @@ def _prep_number(self, obj):
478482

479483
def _prep_datetime(self, obj):
480484
type_ = 'datetime'
481-
obj = datetime_normalize(self.truncate_datetime, obj)
485+
obj = datetime_normalize(self.truncate_datetime, obj, default_timezone=self.default_timezone)
482486
return KEY_TO_VAL_STR.format(type_, obj)
483487

484488
def _prep_date(self, obj):

deepdiff/diff.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# You might need to run it many times since dictionaries come in different orders
66
# every time you run the docstrings.
77
# However the docstring expects it in a specific order in order to pass!
8+
import pytz
89
import difflib
910
import logging
1011
import types
@@ -110,6 +111,7 @@ def _report_progress(_stats, progress_logger, duration):
110111
'ignore_private_variables',
111112
'encodings',
112113
'ignore_encoding_errors',
114+
'default_timezone',
113115
)
114116

115117

@@ -170,6 +172,7 @@ def __init__(self,
170172
verbose_level: int=1,
171173
view: str=TEXT_VIEW,
172174
zip_ordered_iterables: bool=False,
175+
default_timezone:Union[datetime.timezone, datetime.timezone, pytz.tzinfo.BaseTzInfo]=datetime.timezone.utc,
173176
_parameters=None,
174177
_shared_parameters=None,
175178
**kwargs):
@@ -184,7 +187,7 @@ def __init__(self,
184187
"view, hasher, hashes, max_passes, max_diffs, zip_ordered_iterables, "
185188
"cutoff_distance_for_pairs, cutoff_intersection_for_pairs, log_frequency_in_sec, cache_size, "
186189
"cache_tuning_sample_size, get_deep_distance, group_by, group_by_sort_key, cache_purge_level, "
187-
"math_epsilon, iterable_compare_func, use_enum_value, _original_type, threshold_to_diff_deeper, "
190+
"math_epsilon, iterable_compare_func, use_enum_value, _original_type, threshold_to_diff_deeper, default_timezone "
188191
"ignore_order_func, custom_operators, encodings, ignore_encoding_errors, use_log_scale, log_scale_similarity_threshold "
189192
"_parameters and _shared_parameters.") % ', '.join(kwargs.keys()))
190193

@@ -205,6 +208,7 @@ def __init__(self,
205208
self.use_enum_value = use_enum_value
206209
self.log_scale_similarity_threshold = log_scale_similarity_threshold
207210
self.use_log_scale = use_log_scale
211+
self.default_timezone = default_timezone
208212
self.threshold_to_diff_deeper = threshold_to_diff_deeper
209213
self.ignore_string_type_changes = ignore_string_type_changes
210214
self.ignore_type_in_groups = self.get_ignore_types_in_groups(
@@ -1490,17 +1494,17 @@ def _diff_numbers(self, level, local_tree=None, report_type_change=True):
14901494

14911495
def _diff_datetime(self, level, local_tree=None):
14921496
"""Diff DateTimes"""
1493-
level.t1 = datetime_normalize(self.truncate_datetime, level.t1)
1494-
level.t2 = datetime_normalize(self.truncate_datetime, level.t2)
1497+
level.t1 = datetime_normalize(self.truncate_datetime, level.t1, default_timezone=self.default_timezone)
1498+
level.t2 = datetime_normalize(self.truncate_datetime, level.t2, default_timezone=self.default_timezone)
14951499

14961500
if level.t1 != level.t2:
14971501
self._report_result('values_changed', level, local_tree=local_tree)
14981502

14991503
def _diff_time(self, level, local_tree=None):
15001504
"""Diff DateTimes"""
15011505
if self.truncate_datetime:
1502-
level.t1 = datetime_normalize(self.truncate_datetime, level.t1)
1503-
level.t2 = datetime_normalize(self.truncate_datetime, level.t2)
1506+
level.t1 = datetime_normalize(self.truncate_datetime, level.t1, default_timezone=self.default_timezone)
1507+
level.t2 = datetime_normalize(self.truncate_datetime, level.t2, default_timezone=self.default_timezone)
15041508

15051509
if level.t1 != level.t2:
15061510
self._report_result('values_changed', level, local_tree=local_tree)

deepdiff/helper.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import string
99
import time
1010
import enum
11+
import pytz
1112
from typing import NamedTuple, Any, List, Optional, Dict, Union
1213
from ast import literal_eval
1314
from decimal import Decimal, localcontext, InvalidOperation as InvalidDecimalOperation
@@ -605,11 +606,17 @@ def literal_eval_extended(item):
605606
raise
606607

607608

608-
def time_to_seconds(t):
609+
def time_to_seconds(t:datetime.time) -> int:
609610
return (t.hour * 60 + t.minute) * 60 + t.second
610611

611612

612-
def datetime_normalize(truncate_datetime, obj):
613+
def datetime_normalize(
614+
truncate_datetime:Union[str, None],
615+
obj:Union[datetime.datetime, datetime.time],
616+
default_timezone: Union[
617+
datetime.timezone, pytz.tzinfo.BaseTzInfo
618+
] = datetime.timezone.utc,
619+
) -> Any:
613620
if truncate_datetime:
614621
if truncate_datetime == 'second':
615622
obj = obj.replace(microsecond=0)
@@ -621,11 +628,11 @@ def datetime_normalize(truncate_datetime, obj):
621628
obj = obj.replace(hour=0, minute=0, second=0, microsecond=0)
622629
if isinstance(obj, datetime.datetime):
623630
if has_timezone(obj):
624-
obj = obj.astimezone(datetime.timezone.utc)
631+
obj = obj.astimezone(default_timezone)
625632
else:
626-
obj = obj.replace(tzinfo=datetime.timezone.utc)
633+
obj = obj.replace(tzinfo=default_timezone)
627634
elif isinstance(obj, datetime.time):
628-
obj = time_to_seconds(obj)
635+
return time_to_seconds(obj)
629636
return obj
630637

631638

@@ -643,7 +650,7 @@ def has_timezone(dt):
643650
return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
644651

645652

646-
def get_truncate_datetime(truncate_datetime):
653+
def get_truncate_datetime(truncate_datetime) -> Union[str, None]:
647654
"""
648655
Validates truncate_datetime value
649656
"""

tests/test_delta.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import copy
2-
2+
import datetime
33
import pytest
44
import os
55
import io
@@ -1506,6 +1506,7 @@ def test_delta_view_and_to_delta_dict_are_equal_when_parameteres_passed(self):
15061506
'encodings': None,
15071507
'ignore_encoding_errors': False,
15081508
'iterable_compare_func': None,
1509+
'default_timezone': datetime.timezone.utc,
15091510
}
15101511

15111512
expected = {'iterable_items_added_at_indexes': {'root': {1: 1, 2: 1, 3: 1}}, 'iterable_items_removed_at_indexes': {'root': {1: 2, 2: 2}}}

0 commit comments

Comments
 (0)