Skip to content

[Bug] tz_offset shifts datetime which is instantiated with tz argument #553

@yukihiko-shinoda

Description

@yukihiko-shinoda

Correct specification

In nature, the datetime that is created by datetime.now()will be same timestamp even if we set any different tz argument:

from datetime import datetime, timedelta, timezone
from freezegun import freeze_time
from dateutil.tz import tzlocal


def test_freezegun1() -> None:
    timestamp_utc_fixed = int(datetime.now(tz=timezone(timedelta(hours=0))).timestamp() * 1000)
    timestamp_tzlocal = int(datetime.now(tz=tzlocal()).timestamp() * 1000)
    # - Answer: datetime - Python: Figure out local timezone - Stack Overflow
    #   https://stackoverflow.com/a/39079819/12721873
    timestamp_local_timezone = int(datetime.now(tz=datetime.now(timezone.utc).astimezone().tzinfo).timestamp() * 1000)
    timestamp_no_tz = int(datetime.now().timestamp() * 1000)
    assert timestamp_utc_fixed == timestamp_no_tz
    assert timestamp_tzlocal == timestamp_no_tz
    assert timestamp_local_timezone == timestamp_no_tz

cf: The specification of datetime.datetime.timestamp():
datetime — Basic date and time types — Python 3.12.4 documentation

Bug details

When we use freeze_time() with argument: tz_offset,
the datetime that is created by datetime.now() with the argument: tz was shifted as same as tz_offset
against the datetime that is created by datetime.now() without the argument: tz:

from datetime import datetime, timedelta, timezone
from freezegun import freeze_time
from dateutil.tz import tzlocal


DIFFERENCE_TIMESTAMP_JST = 9 * 60 * 60 * 1000


@freeze_time("2022-08-09 11:26:00.000", tz_offset=-9)
def test_freezegun2() -> None:
    timestamp_utc_fixed = int(datetime.now(tz=timezone(timedelta(hours=0))).timestamp() * 1000)
    timestamp_tzlocal = int(datetime.now(tz=tzlocal()).timestamp() * 1000)
    # - Answer: datetime - Python: Figure out local timezone - Stack Overflow
    #   https://stackoverflow.com/a/39079819/12721873
    timestamp_local_timezone = int(datetime.now(tz=datetime.now(timezone.utc).astimezone().tzinfo).timestamp() * 1000)
    timestamp_no_tz = int(datetime.now().timestamp() * 1000)
    assert timestamp_utc_fixed + DIFFERENCE_TIMESTAMP_JST == timestamp_no_tz  # Wrong!
    assert timestamp_tzlocal + DIFFERENCE_TIMESTAMP_JST == timestamp_no_tz  # Wrong!
    assert timestamp_local_timezone + DIFFERENCE_TIMESTAMP_JST == timestamp_no_tz  # Wrong!

In case when we don't set tz_offset, there wasn't any problems.:

from datetime import datetime, timedelta, timezone
from freezegun import freeze_time
from dateutil.tz import tzlocal


@freeze_time("2022-08-09 11:26:00.000")
def test_freezegun3() -> None:
    timestamp_utc_fixed = int(datetime.now(tz=timezone(timedelta(hours=0))).timestamp() * 1000)
    timestamp_tzlocal = int(datetime.now(tz=tzlocal()).timestamp() * 1000)
    # - Answer: datetime - Python: Figure out local timezone - Stack Overflow
    #   https://stackoverflow.com/a/39079819/12721873
    timestamp_local_timezone = int(datetime.now(tz=datetime.now(timezone.utc).astimezone().tzinfo).timestamp() * 1000)
    timestamp_no_tz = int(datetime.now().timestamp() * 1000)
    assert timestamp_utc_fixed == timestamp_no_tz
    assert timestamp_tzlocal == timestamp_no_tz
    assert timestamp_local_timezone == timestamp_no_tz

these tests seems to work fine with any local timezone.

Tested version:

Python: 3.12.4
freezegun: 1.5.1

Related?:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions