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

rahulvats pushed a commit to branch backport-62510
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 830902228af71d28056da6d369199024ced02e22
Author: yuseok89 <[email protected]>
AuthorDate: Sat Jan 31 01:25:21 2026 +0900

    fix(ui): use ISO dates in Gantt chart for cross-browser consistency (#61250)
    
    (cherry picked from commit 705107621ca10fed635b0374ab1b9ca46b11766f)
---
 .../src/airflow/ui/src/layouts/Details/Gantt/Gantt.tsx  | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Gantt/Gantt.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Gantt/Gantt.tsx
index 54d2c476b41..7dec8f4354e 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Gantt/Gantt.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Gantt/Gantt.tsx
@@ -52,7 +52,6 @@ import { useGridStructure } from 
"src/queries/useGridStructure";
 import { useGridTiSummaries } from "src/queries/useGridTISummaries";
 import { getComputedCSSVariableValue } from "src/theme";
 import { isStatePending, useAutoRefresh } from "src/utils";
-import { DEFAULT_DATETIME_FORMAT_WITH_TZ, formatDate } from 
"src/utils/datetimeUtils";
 
 import { createHandleBarClick, createHandleBarHover, createChartOptions } from 
"./utils";
 
@@ -144,8 +143,6 @@ export const Gantt = ({ limit, runType, triggeringUser }: 
Props) => {
 
   const isLoading = runsLoading || structureLoading || summariesLoading || 
tiLoading;
 
-  const currentTime = 
dayjs().tz(selectedTimezone).format(DEFAULT_DATETIME_FORMAT_WITH_TZ);
-
   const data = useMemo(() => {
     if (isLoading || runId === "") {
       return [];
@@ -159,15 +156,15 @@ export const Gantt = ({ limit, runType, triggeringUser }: 
Props) => {
         const gridSummary = gridSummaries.find((ti) => ti.task_id === node.id);
 
         if ((node.isGroup ?? node.is_mapped) && gridSummary) {
-          // Use min/max times from grid summary
+          // Use min/max times from grid summary; ISO so time scale and bar 
positions render consistently across browsers
           return {
             isGroup: node.isGroup,
             isMapped: node.is_mapped,
             state: gridSummary.state,
             taskId: gridSummary.task_id,
             x: [
-              formatDate(gridSummary.min_start_date, selectedTimezone, 
DEFAULT_DATETIME_FORMAT_WITH_TZ),
-              formatDate(gridSummary.max_end_date, selectedTimezone, 
DEFAULT_DATETIME_FORMAT_WITH_TZ),
+                  dayjs(gridSummary.min_start_date).toISOString(),
+                  dayjs(gridSummary.max_end_date).toISOString(),
             ],
             y: gridSummary.task_id,
           };
@@ -177,17 +174,15 @@ export const Gantt = ({ limit, runType, triggeringUser }: 
Props) => {
 
           if (taskInstance) {
             const hasTaskRunning = isStatePending(taskInstance.state);
-            const endTime = hasTaskRunning ? currentTime : 
taskInstance.end_date;
+            const endTime = hasTaskRunning ? dayjs().toISOString() : 
taskInstance.end_date;
+
 
             return {
               isGroup: node.isGroup,
               isMapped: node.is_mapped,
               state: taskInstance.state,
               taskId: taskInstance.task_id,
-              x: [
-                formatDate(taskInstance.start_date, selectedTimezone, 
DEFAULT_DATETIME_FORMAT_WITH_TZ),
-                formatDate(endTime, selectedTimezone, 
DEFAULT_DATETIME_FORMAT_WITH_TZ),
-              ],
+              x: [dayjs(taskInstance.start_date).toISOString(), 
dayjs(endTime).toISOString()],
               y: taskInstance.task_id,
             };
           }

Reply via email to