From c01bbf20586f8fe77bdd8b06e318deb826c556d4 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 24 Jul 2019 14:09:52 +0100 Subject: [PATCH] Timerange: Fixes a bug where custom time ranges didn't respect UTC (#18248) Closes #18170 Closes #18178 --- packages/grafana-data/src/utils/datemath.ts | 12 ++++++++++++ .../src/components/TimePicker/TimePicker.tsx | 15 ++++++++++++--- .../components/DashNav/DashNavTimeControls.tsx | 8 +++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/grafana-data/src/utils/datemath.ts b/packages/grafana-data/src/utils/datemath.ts index 5b614606f7c..3b033e9cc6d 100644 --- a/packages/grafana-data/src/utils/datemath.ts +++ b/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. diff --git a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx index fe401b588f6..a3a59f8d25b 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx +++ b/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 { 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 && Custom time range} {!isCustomOpen && {rangeString}} - {timeZone === 'utc' && UTC} + {isUTC && UTC} ); const isAbsolute = isDateTime(value.raw.to); diff --git a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx b/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx index a872f1ba432..bdb8f810d6b 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx +++ b/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 { 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);