Skip to content

Fix instance() ignoring the tz argument for aware datetimes - #1049

Open
developer-rpai wants to merge 1 commit into
python-pendulum:masterfrom
developer-rpai:fix-841-instance-tz
Open

developer-rpai wants to merge 1 commit into
python-pendulum:masterfrom
developer-rpai:fix-841-instance-tz

Conversation

@developer-rpai

Copy link
Copy Markdown

Fixes #841.

pendulum.instance(dt, tz="EST") silently ignored the tz argument whenever dt already carried a timezone: DateTime.instance() unconditionally preferred dt.tzinfo, so no conversion ever happened and the returned value kept the original timezone.

This makes an explicitly passed timezone take precedence:

  • Aware datetimes are converted to the given timezone (the instant is preserved).
  • Naive datetimes are interpreted in the given timezone, as before.
  • When no timezone is passed, behavior is unchanged: aware datetimes keep their timezone and naive ones default to UTC. To make that distinction possible, the tz parameter of instance() (and of DateTime.instance() / Time.instance()) now defaults to None.

Two follow-on adjustments were needed:

  • DateTime.utcfromtimestamp(), DateTime.fromordinal() and DateTime.combine() used to pass tz=None through instance() to get a naive result, so they now build their result directly. Their behavior is unchanged (a tzinfo given to combine() now wins over the time's own tzinfo, matching the standard library).
  • The parser forwarded its tz option to instance() with a UTC default, which would have turned an unspecified option into an explicit conversion request; it now forwards the option only when one was actually given.

Tests: the full suite passes (1875 passed, 3 skipped), including new regression tests in tests/test_main.py covering conversion for both pendulum.instance() and DateTime.instance(), the reporter's pendulum DateTime case, and naive datetimes with an explicit timezone.

The tz argument of pendulum.instance() and DateTime.instance() was
silently ignored whenever the given datetime already carried a
timezone: the datetime's own tzinfo always won and no conversion
happened.

An explicitly passed timezone now takes precedence. Aware datetimes
are converted to it, naive ones are interpreted in it as before. When
no timezone is passed, the previous behavior is unchanged: aware
datetimes keep their timezone and naive ones default to UTC.

DateTime.utcfromtimestamp(), fromordinal() and combine() relied on
passing tz=None to stay naive, so they now build their result
directly instead of going through instance().

@Wkhanex Wkhanex left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the changed DateTime.instance method with a datetime adapter and ZoneInfo conversion hooks. Four conversions covering both folds of New York’s 2024 fall-back hour to UTC and Brussels preserved the original timestamp. Default-aware input retained its timezone, explicit-zone naive input retained its wall time, and default-naive input used UTC. Those controls support the distinction between converting aware inputs and interpreting naive inputs. Consider a DST-fold regression alongside the new ordinary-date tests. I ran these checks on Python 3.12; isolated method checks, not the full Pendulum parser/timezone suite.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tz not taken into account when calling pendulum.instance

2 participants