This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch issue28931
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 78165ada809f811c86828cf527b61a6029e0a3d3
Author: Evan Rusackas <e...@rusackas.com>
AuthorDate: Tue Aug 5 13:08:43 2025 -0700

    fix(calendar): Fix day offset in Calendar Heatmap visualization
    
    Fixes #28931
    
    The Calendar Heatmap was displaying dates one day off due to incorrect
    timezone offset adjustment in the frontend. The timestamps are already
    in UTC from the backend and should be displayed without local timezone
    conversion.
    
    - Removed unnecessary timezone offset calculation in getFormattedUTCTime
    - Added comprehensive tests to verify dates display correctly
    - Tested with various edge cases including dates near midnight
    
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-Authored-By: Claude <nore...@anthropic.com>
---
 .../legacy-plugin-chart-calendar/src/utils.ts      |  5 ++--
 ...attedUTCTime.ts => getFormattedUTCTime.test.ts} | 30 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git 
a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/utils.ts 
b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/utils.ts
index 9f3c0bee1b..99d7e112e2 100644
--- a/superset-frontend/plugins/legacy-plugin-chart-calendar/src/utils.ts
+++ b/superset-frontend/plugins/legacy-plugin-chart-calendar/src/utils.ts
@@ -25,6 +25,7 @@ export const getFormattedUTCTime = (
   timeFormat?: string,
 ) => {
   const date = new Date(ts);
-  const offset = date.getTimezoneOffset() * 60 * 1000;
-  return getTimeFormatter(timeFormat)(date.getTime() - offset);
+  // No need to adjust for timezone offset - the timestamp is already in UTC
+  // and should be displayed as such without local timezone conversion
+  return getTimeFormatter(timeFormat)(date.getTime());
 };
diff --git 
a/superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.ts
 
b/superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.test.ts
similarity index 54%
rename from 
superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.ts
rename to 
superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.test.ts
index 535542e868..690da7d854 100644
--- 
a/superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.ts
+++ 
b/superset-frontend/plugins/legacy-plugin-chart-calendar/test/getFormattedUTCTime.test.ts
@@ -25,4 +25,34 @@ describe('getFormattedUTCTime', () => {
     const formattedTime = getFormattedUTCTime(ts, '%Y-%m-%d %H:%M:%S');
     expect(formattedTime).toEqual('2015-01-01 00:00:00');
   });
+
+  it('should not have day offset for dates near midnight', () => {
+    // Test case from issue #28931 - 2024-05-31 should remain 2024-05-31
+    const ts = new Date('2024-05-31T00:00:00Z').getTime();
+    const formattedTime = getFormattedUTCTime(ts, '%Y-%m-%d');
+    expect(formattedTime).toEqual('2024-05-31');
+  });
+
+  it('should handle different timezones without offset', () => {
+    // Test various timestamps to ensure no day shifting occurs
+    const testCases = [
+      {
+        ts: new Date('2024-05-31T23:59:59Z').getTime(),
+        expected: '2024-05-31',
+      },
+      {
+        ts: new Date('2024-06-01T00:00:00Z').getTime(),
+        expected: '2024-06-01',
+      },
+      {
+        ts: new Date('2024-01-01T12:00:00Z').getTime(),
+        expected: '2024-01-01',
+      },
+    ];
+
+    testCases.forEach(({ ts, expected }) => {
+      const formattedTime = getFormattedUTCTime(ts, '%Y-%m-%d');
+      expect(formattedTime).toEqual(expected);
+    });
+  });
 });

Reply via email to