Skip to content

fix(util): Decode partition dates as UTC regardless of the host timezone - #8562

Open
RaphaelFakhri wants to merge 1 commit into
getsentry:masterfrom
RaphaelFakhri:fix/decode-part-str-local-timezone
Open

RaphaelFakhri wants to merge 1 commit into
getsentry:masterfrom
RaphaelFakhri:fix/decode-part-str-local-timezone

Conversation

@RaphaelFakhri

Copy link
Copy Markdown

decode_part_str parses the partition date with datetime.strptime(...), which returns a naive datetime, and then calls .astimezone(UTC). Python treats a naive datetime passed to astimezone() as local time, so on a host whose TZ is east of UTC the decoded date moves to the previous day. For example, with TZ=Asia/Tokyo the partition (90,'2026-10-12') (a Monday) decodes as 2026-10-11 15:00 UTC (a Sunday).

Every caller assumes the decoded date is the partition's Monday:

  • snuba cleanup: filter_stale_partitions computes the partition's last day as the end of the week, which becomes the Sunday before the partition starts. Partitions are dropped 7 days early, while they still hold data inside the retention window.
  • Lightweight deletes: _get_partition_dates returns 2026-10-11, and the split delete filters on toMonday(timestamp) = '2026-10-11'. That condition matches no rows, so the delete removes nothing for that partition and the partition is still recorded as done.
  • snuba optimize --before: the cutoff comparison is off by a week.

This change uses .replace(tzinfo=UTC) so the date is always the partition's UTC date. Hosts running with TZ=UTC (or a zone west of UTC) see no change.

The new test in tests/test_util.py sets TZ=Asia/Tokyo and checks that decode_part_str returns the Monday at midnight UTC. It fails before this change and passes after.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

Fixes #8561

decode_part_str called .astimezone(UTC) on the naive datetime returned
by strptime, which Python interprets as local time. On hosts east of
UTC the Monday partition date became the previous Sunday, so cleanup
dropped partitions a week early and partition-split lightweight deletes
matched no rows.
@RaphaelFakhri
RaphaelFakhri requested a review from a team as a code owner October 19, 2026 08:28
Comment thread tests/test_util.py
@pytest.fixture
def local_timezone(monkeypatch: pytest.MonkeyPatch) -> Generator[None]:
# A zone east of UTC, where local midnight falls on the previous UTC day.
monkeypatch.setenv("TZ", "Asia/Tokyo")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd use a context manager here - something like

@pytest.fixture
  def local_timezone(monkeypatch: pytest.MonkeyPatch) -> Generator[None]:
      with monkeypatch.context() as m:
          m.setenv("TZ", "Asia/Tokyo")
          time.tzset()
          yield
      time.tzset()

avoids calling monkeypatch.undo()

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.

Partition dates decode to the previous day when the host timezone is east of UTC

2 participants