From eddaac61b24dba1944eabd9c3ef34ec36597905e Mon Sep 17 00:00:00 2001 From: Prashant Sharma <31796326+gutsytechster@users.noreply.github.com> Date: Wed, 22 Mar 2023 20:03:01 +0530 Subject: [PATCH] Use timezone via settings to get PREFER_DATES_FROM result (#1155) * tests(test_date_parser.py): add test when timezone is provided via settings * fix(dateparser/parser.py): consider timezone provided via settings * fix(dateparser/parser.py): fetch timezone details through inbuilt method This ensures that we are still processing times such as EDT or AEDT which returns UnknownTimezoneError with pytz.timezone method. --- dateparser/parser.py | 11 ++++++++--- tests/test_date_parser.py | 33 +++++++++++++-------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/dateparser/parser.py b/dateparser/parser.py index 5c0aeba23..77154c8b0 100644 --- a/dateparser/parser.py +++ b/dateparser/parser.py @@ -1,15 +1,15 @@ import calendar import regex as re +import pytz from io import StringIO from collections import OrderedDict from datetime import datetime from datetime import timedelta -from pytz import utc from dateparser.utils import set_correct_day_from_settings, \ get_last_day_of_month, get_previous_leap_year, get_next_leap_year, \ - _get_missing_parts + _get_missing_parts, get_timezone_from_tz_string from dateparser.utils.strptime import strptime @@ -460,7 +460,7 @@ def _correct_for_time_frame(self, dateobj, tz): # Since date comparisons must be either offset-naive or offset-aware, normalize dateobj # to be offset-aware if one or the other is already offset-aware. if self.now.tzinfo is not None and dateobj.tzinfo is None: - dateobj = utc.localize(dateobj) + dateobj = pytz.utc.localize(dateobj) if self.month and not self.year: try: @@ -491,6 +491,11 @@ def _correct_for_time_frame(self, dateobj, tz): self._token_day, hasattr(self, '_token_weekday')]): # Convert dateobj to utc time to compare with self.now + try: + tz = tz or get_timezone_from_tz_string(self.settings.TIMEZONE) + except pytz.UnknownTimeZoneError: + tz = None + if tz: dateobj_time = (dateobj - tz.utcoffset(dateobj)).time() else: diff --git a/tests/test_date_parser.py b/tests/test_date_parser.py index a6e459d26..dad297583 100644 --- a/tests/test_date_parser.py +++ b/tests/test_date_parser.py @@ -869,27 +869,20 @@ def test_parsing_strings_containing_only_separator_tokens(self, date_string, exp self.then_date_obj_exactly_is(expected) @parameterized.expand([ - param('4pm EDT', datetime(2021, 10, 19, 20, 0)), + param('4pm EDT', datetime(2021, 10, 19, 20, 0), {'PREFER_DATES_FROM': 'future'}), + param('11pm AEDT', datetime(2021, 10, 19, 12, 0), {'PREFER_DATES_FROM': 'past'}), + param('4pm', datetime(2021, 10, 19, 20, 0), {'PREFER_DATES_FROM': 'future', 'TIMEZONE': 'EDT'}), + param('11pm', datetime(2021, 10, 19, 12, 0), {'PREFER_DATES_FROM': 'past', 'TIMEZONE': 'AEDT'}), ]) - def test_date_skip_ahead(self, date_string, expected): - self.given_parser(settings={'PREFER_DATES_FROM': 'future', - 'TO_TIMEZONE': 'etc/utc', - 'RETURN_AS_TIMEZONE_AWARE': False, - 'RELATIVE_BASE': datetime(2021, 10, 19, 18, 0), - }) - self.when_date_is_parsed(date_string) - self.then_date_was_parsed_by_date_parser() - self.then_date_obj_exactly_is(expected) - - @parameterized.expand([ - param('11pm AEDT', datetime(2021, 10, 19, 12, 0)), - ]) - def test_date_step_back(self, date_string, expected): - self.given_parser(settings={'PREFER_DATES_FROM': 'past', - 'TO_TIMEZONE': 'etc/utc', - 'RETURN_AS_TIMEZONE_AWARE': False, - 'RELATIVE_BASE': datetime(2021, 10, 19, 18, 0), - }) + def test_prefer_dates_from_with_timezone(self, date_string, expected, test_settings): + self.given_parser( + settings={ + 'TO_TIMEZONE': 'etc/utc', + 'RETURN_AS_TIMEZONE_AWARE': False, + 'RELATIVE_BASE': datetime(2021, 10, 19, 18, 0), + **test_settings + } + ) self.when_date_is_parsed(date_string) self.then_date_was_parsed_by_date_parser() self.then_date_obj_exactly_is(expected)