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 d69877fd968..646a99a90bd 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx @@ -14,6 +14,7 @@ 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 adjustedTo = isUTC ? value.to.utc() : value.to.local(); + const adjustedFrom = isUTC ? value.from.utc() : value.from.local(); + const adjustedTimeRange = { + to: isMathString(value.raw.to) ? value.raw.to : adjustedTo, + from: isMathString(value.raw.from) ? value.raw.from : adjustedFrom, + }; + 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);