Browse Source

Timerange: Fixes a bug where custom time ranges didn't respect UTC (#18248)

Closes #18170
Closes #18178
kay delaney 6 năm trước cách đây
mục cha
commit
c01bbf2058

+ 12 - 0
packages/grafana-data/src/utils/datemath.ts

@@ -5,6 +5,18 @@ import { TimeZone } from '../types';
 
 const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
 
+export function isMathString(text: string | DateTime | Date): boolean {
+  if (!text) {
+    return false;
+  }
+
+  if (typeof text === 'string' && (text.substring(0, 3) === 'now' || text.includes('||'))) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
 /**
  * Parses different types input to a moment instance. There is a specific formatting language that can be used
  * if text arg is string. See unit tests for examples.

+ 12 - 3
packages/grafana-ui/src/components/TimePicker/TimePicker.tsx

@@ -8,12 +8,13 @@ import { TimePickerPopover } from './TimePickerPopover';
 import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper';
 
 // Utils & Services
-import { isDateTime } from '@grafana/data';
+import { isDateTime, DateTime } from '@grafana/data';
 import { rangeUtil } from '@grafana/data';
 import { rawToTimeRange } from './time';
 
 // Types
 import { TimeRange, TimeOption, TimeZone, TIME_FORMAT, SelectableValue } from '@grafana/data';
+import { isMathString } from '@grafana/data/src/utils/datemath';
 
 export interface Props {
   value: TimeRange;
@@ -123,13 +124,21 @@ export class TimePicker extends PureComponent<Props, State> {
     const { isCustomOpen } = this.state;
     const options = this.mapTimeOptionsToSelectableValues(selectTimeOptions);
     const currentOption = options.find(item => isTimeOptionEqualToTimeRange(item.value, value));
-    const rangeString = rangeUtil.describeTimeRange(value.raw);
+
+    const isUTC = timeZone === 'utc';
+
+    const adjustedTime = (time: DateTime) => (isUTC ? time.utc() : time.local()) || null;
+    const adjustedTimeRange = {
+      to: isMathString(value.raw.to) ? value.raw.to : adjustedTime(value.to),
+      from: isMathString(value.raw.from) ? value.raw.from : adjustedTime(value.from),
+    };
+    const rangeString = rangeUtil.describeTimeRange(adjustedTimeRange);
 
     const label = (
       <>
         {isCustomOpen && <span>Custom time range</span>}
         {!isCustomOpen && <span>{rangeString}</span>}
-        {timeZone === 'utc' && <span className="time-picker-utc">UTC</span>}
+        {isUTC && <span className="time-picker-utc">UTC</span>}
       </>
     );
     const isAbsolute = isDateTime(value.raw.to);

+ 5 - 3
public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx

@@ -1,6 +1,6 @@
 // Libaries
 import React, { Component } from 'react';
-import { toUtc } from '@grafana/data';
+import { toUtc, dateMath } from '@grafana/data';
 
 // Types
 import { DashboardModel } from '../../state';
@@ -61,9 +61,11 @@ export class DashNavTimeControls extends Component<Props> {
     const panel = dashboard.timepicker;
     const hasDelay = panel.nowDelay && timeRange.raw.to === 'now';
 
+    const adjustedFrom = dateMath.isMathString(timeRange.raw.from) ? timeRange.raw.from : timeRange.from;
+    const adjustedTo = dateMath.isMathString(timeRange.raw.to) ? timeRange.raw.to : timeRange.to;
     const nextRange = {
-      from: timeRange.raw.from,
-      to: hasDelay ? 'now-' + panel.nowDelay : timeRange.raw.to,
+      from: adjustedFrom,
+      to: hasDelay ? 'now-' + panel.nowDelay : adjustedTo,
     };
 
     this.timeSrv.setTime(nextRange);