diff --git a/freezegun/api.py b/freezegun/api.py index 81d4da17..3dd83b52 100644 --- a/freezegun/api.py +++ b/freezegun/api.py @@ -295,7 +295,8 @@ def datetime_to_fakedatetime(datetime): datetime.minute, datetime.second, datetime.microsecond, - datetime.tzinfo) + datetime.tzinfo, + fold=datetime.fold) def date_to_fakedate(date): @@ -385,9 +386,14 @@ def timestamp(self): def now(cls, tz=None): now = cls._time_to_freeze() or real_datetime.now() if tz: - result = tz.fromutc(now.replace(tzinfo=tz)) + cls._tz_offset() + result = tz.fromutc(now.replace(tzinfo=tz)) else: - result = now + cls._tz_offset() + result = now + + # Add the _tz_offset only if it's non-zero to preserve fold + if cls._tz_offset(): + result += cls._tz_offset() + return datetime_to_fakedatetime(result) def date(self): diff --git a/tests/test_operations.py b/tests/test_operations.py index 303a1dc8..f61b8fb6 100644 --- a/tests/test_operations.py +++ b/tests/test_operations.py @@ -1,5 +1,6 @@ import datetime from freezegun import freeze_time +from dateutil import tz from dateutil.relativedelta import relativedelta from datetime import timedelta, tzinfo from tests import utils @@ -63,6 +64,15 @@ def test_datetime_timezone_real(): assert now.utcoffset() == timedelta(0, 60 * 60 * 5) +@freeze_time("2021-10-31 02:30:00+01:00") # This will have fold set to 1 +def test_datetime_timezone_real_fold(): + vienna = tz.gettz("Europe/Vienna") + now = datetime.datetime.now(tz=vienna) + assert now == datetime.datetime(2021, 10, 31, 2, 30, tzinfo=vienna) + assert now.utcoffset() == timedelta(0, 60 * 60 * 1) + assert now.fold == 1 + + @freeze_time("2012-01-14 2:00:00", tz_offset=-4) def test_datetime_timezone_real_with_offset(): now = datetime.datetime.now(tz=GMT5()) @@ -70,6 +80,16 @@ def test_datetime_timezone_real_with_offset(): assert now.utcoffset() == timedelta(0, 60 * 60 * 5) +@freeze_time("2021-10-31 06:30:00+01:00", tz_offset=-4) +def test_datetime_timezone_real_with_offset_fold(): + vienna = tz.gettz("Europe/Vienna") + now = datetime.datetime.now(tz=vienna) + assert now == datetime.datetime(2021, 10, 31, 2, 30, tzinfo=vienna) + # Because of adding the tz_offset timedelta, fold information is lost + assert now.utcoffset() == timedelta(0, 60 * 60 * 2) + assert now.fold == 0 + + @freeze_time("2012-01-14 00:00:00") def test_astimezone(): now = datetime.datetime.now(tz=GMT5())