From bc091c6c1cb46a731c9632cd53ab3efb8962046c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Oberm=C3=BCller?= Date: Wed, 6 Sep 2023 17:12:39 +0200 Subject: [PATCH] fix(retention): handle timezones with daylight saving transitions correctly (#17305) --- frontend/src/scenes/retention/retentionLineGraphLogic.ts | 2 +- frontend/src/scenes/retention/retentionTableLogic.ts | 2 +- posthog/queries/retention/retention.py | 6 ++++-- posthog/queries/test/test_retention.py | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/src/scenes/retention/retentionLineGraphLogic.ts b/frontend/src/scenes/retention/retentionLineGraphLogic.ts index f0624e1599954..2926ada9e6255 100644 --- a/frontend/src/scenes/retention/retentionLineGraphLogic.ts +++ b/frontend/src/scenes/retention/retentionLineGraphLogic.ts @@ -71,7 +71,7 @@ export const retentionLineGraphLogic = kea({ label: cohortRetention.date ? period === 'Hour' ? dayjs(cohortRetention.date).format('MMM D, h A') - : dayjs.utc(cohortRetention.date).format('MMM D') + : dayjs(cohortRetention.date).format('MMM D') : cohortRetention.label, data: retention_reference === 'previous' diff --git a/frontend/src/scenes/retention/retentionTableLogic.ts b/frontend/src/scenes/retention/retentionTableLogic.ts index 9dfacbc58433c..13d512f34183f 100644 --- a/frontend/src/scenes/retention/retentionTableLogic.ts +++ b/frontend/src/scenes/retention/retentionTableLogic.ts @@ -73,7 +73,7 @@ export const retentionTableLogic = kea({ ? results[rowIndex].label : period === 'Hour' ? dayjs(results[rowIndex].date).format('MMM D, h A') - : dayjs.utc(results[rowIndex].date).format('MMM D'), + : dayjs(results[rowIndex].date).format('MMM D'), // Second column is the first value (which is essentially the total) results[rowIndex].values[0].count, // All other columns are rendered as percentage diff --git a/posthog/queries/retention/retention.py b/posthog/queries/retention/retention.py index b5f5a08620a1e..dc8f41175521d 100644 --- a/posthog/queries/retention/retention.py +++ b/posthog/queries/retention/retention.py @@ -109,8 +109,10 @@ def construct_url(first_day): for day in range(filter.total_intervals - first_day) ], "label": "{} {}".format(filter.period, first_day), - "date": (filter.date_from + RetentionFilter.determine_time_delta(first_day, filter.period)[0]).replace( - tzinfo=pytz.timezone(team.timezone) + "date": pytz.timezone(team.timezone).localize( + (filter.date_from + RetentionFilter.determine_time_delta(first_day, filter.period)[0]).replace( + tzinfo=None + ) ), "people_url": construct_url(first_day), } diff --git a/posthog/queries/test/test_retention.py b/posthog/queries/test/test_retention.py index c8d889f19f7bb..7f49141447b9a 100644 --- a/posthog/queries/test/test_retention.py +++ b/posthog/queries/test/test_retention.py @@ -1270,7 +1270,8 @@ def test_timezones(self): ["Day 0", "Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7", "Day 8", "Day 9", "Day 10"], ) - self.assertEqual(result_pacific[0]["date"], datetime(2020, 6, 10, 0, tzinfo=pytz.timezone("US/Pacific"))) + self.assertEqual(result_pacific[0]["date"], pytz.timezone("US/Pacific").localize(datetime(2020, 6, 10))) + self.assertEqual(result_pacific[0]["date"].isoformat(), "2020-06-10T00:00:00-07:00") self.assertEqual( pluck(result, "values", "count"),