From e3e7086a91c706206217237906e69d76c27aba12 Mon Sep 17 00:00:00 2001 From: Oscar Kilhed Date: Thu, 12 Dec 2024 10:22:49 +0100 Subject: [PATCH] GrafanaData: Add now parameter to dateMath.parse to subsitute now string (#97151) * Add now parameter to dateMath.parse to subsitute now string * Create new function, deprecate the old * Add docstring * Typo --- .../grafana-data/src/datetime/datemath.ts | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/packages/grafana-data/src/datetime/datemath.ts b/packages/grafana-data/src/datetime/datemath.ts index e95e4575401..1392e5d3544 100644 --- a/packages/grafana-data/src/datetime/datemath.ts +++ b/packages/grafana-data/src/datetime/datemath.ts @@ -1,12 +1,13 @@ import { isDate } from 'lodash'; -import { TimeZone } from '../types/time'; +import { TimeZone } from '@grafana/schema'; import { DateTime, dateTime, dateTimeAsMoment, dateTimeForTimeZone, + DateTimeInput, DurationUnit, isDateTime, ISO_8601, @@ -35,6 +36,7 @@ export function isMathString(text: string | DateTime | Date): boolean { } /** + * @deprecated use toDateTime instead * 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. * @param text @@ -50,14 +52,41 @@ export function parse( if (!text) { return undefined; } + return toDateTime(text, { roundUp, timezone, fiscalYearStartMonth }); +} - if (typeof text !== 'string') { - if (isDateTime(text)) { - return text; +export interface ConversionOptions { + /** + * Set the time to endOf time unit, otherwise to startOf time unit. + */ + roundUp?: boolean; + /** + * Only string 'utc' is acceptable here, for anything else, local timezone is used. + */ + timezone?: TimeZone; + /** + * Setting for which month is the first month of the fiscal year. + */ + fiscalYearStartMonth?: number; + /** + * DateTimeInput to use as now. Useful when parsing multiple values and now needs to be the same. Without this, comparing results from subsequent parses is not guaranteed to be deterministic. + */ + now?: DateTimeInput; +} + +/** + * @param dateTimeRep A DateTime object, a Date object or a string representation of a specific time. + * @param options Options for converting to DateTime + * @returns A DateTime object if possible, undefined if not. + */ +export function toDateTime(dateTimeRep: string | DateTime | Date, options: ConversionOptions): DateTime | undefined { + if (typeof dateTimeRep !== 'string') { + if (isDateTime(dateTimeRep)) { + return dateTimeRep; } - if (isDate(text)) { - return dateTime(text); + if (isDate(dateTimeRep)) { + return dateTime(dateTimeRep); } // We got some non string which is not a moment nor Date. TS should be able to check for that but not always. @@ -68,17 +97,17 @@ export function parse( let index = -1; let parseString = ''; - if (text.substring(0, 3) === 'now') { - time = dateTimeForTimeZone(timezone); - mathString = text.substring('now'.length); + if (dateTimeRep.substring(0, 3) === 'now') { + time = dateTimeForTimeZone(options.timezone, options.now); + mathString = dateTimeRep.substring('now'.length); } else { - index = text.indexOf('||'); + index = dateTimeRep.indexOf('||'); if (index === -1) { - parseString = text; + parseString = dateTimeRep; mathString = ''; // nothing else } else { - parseString = text.substring(0, index); - mathString = text.substring(index + 2); + parseString = dateTimeRep.substring(0, index); + mathString = dateTimeRep.substring(index + 2); } // We're going to just require ISO8601 timestamps, k? time = dateTime(parseString, ISO_8601); @@ -88,7 +117,7 @@ export function parse( return time; } - return parseDateMath(mathString, time, roundUp, fiscalYearStartMonth); + return parseDateMath(mathString, time, options.roundUp, options.fiscalYearStartMonth); } }