Skip to content

naturaldate() gives the wrong answer for tz-aware datetimes #152

@edschofield

Description

@edschofield

The calculation in naturaldate() of how many days ahead or behind a date is, is incorrect for tz-aware datetimes.

Consider when the current time is 2023-10-15 23:00:00+00:00 (UTC). In various other timezones this is:

AEDT: 2023-10-16 10:00:00+11:00
CEST: 2023-10-16 01:00:00+02:00
EDT: 2023-10-15 19:00:00-04:00
PDT: 2023-10-15 16:00:00-07:00

Now consider a time 7 hours in the future. Will that be "today" or "tomorrow"? Relative to UTC this should be "tomorrow", but for the other timezones we would expect:

  • AEDT: today
  • CEST: today
  • EDT: tomorrow
  • PDT: today

So all the following test cases should pass, but the test cases for AEDT and CEST currently fail:

def test_naturaldate_tz_aware():
    utc = dt.timezone.utc
    aedt = dt.timezone(dt.timedelta(hours=11))
    cest = dt.timezone(dt.timedelta(hours=2))
    edt = dt.timezone(dt.timedelta(hours=-4))
    pdt = dt.timezone(dt.timedelta(hours=-7))
    future = dt.datetime(2023, 10, 16, hour=6, tzinfo=utc)

    with freeze_time('2023-10-15 23:00:00+00:00'):
        # We want to know whether 7 hours in the future is "today" or
        # "tomorrow":
        # Now in UTC:     2023-10-15 23:00:00+00:00
        # Future in UTC:  2023-10-16 06:00:00+00:00
        assert humanize.naturaldate(future) == "tomorrow"

        # Now in AEDT:    2023-10-16 10:00:00+11:00
        # Future in AEDT: 2023-10-16 17:00:00+11:00
        assert humanize.naturaldate(future.astimezone(aedt)) == "today"  # FAILS

        # Now in CEST:    2023-10-16 01:00:00+02:00
        # Future in CEST: 2023-10-16 08:00:00+02:00
        assert humanize.naturaldate(future.astimezone(cest)) == "today"  # FAILS

        # Now in EDT:     2023-10-15 19:00:00-04:00
        # Future in EDT:  2023-10-16 02:00:00-04:00
        assert humanize.naturaldate(future.astimezone(edt)) == "tomorrow"

        # Now in PDT:     2023-10-15 16:00:00-07:00
        # Future in PDT:  2023-10-15 23:00:00-07:00
        assert humanize.naturaldate(future.astimezone(pdt)) == "today"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions