mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 00:25:46 -06:00
Co-authored-by: Ryan McKinley <ryantxu@gmail.com> Co-authored-by: Adela Almasan <adela.almasan@grafana.com>
173 lines
4.1 KiB
TypeScript
173 lines
4.1 KiB
TypeScript
import { AbsoluteTimeRange, dateTime, TimeRange } from '@grafana/data';
|
|
|
|
export interface TimeRegionConfig {
|
|
from?: string;
|
|
fromDayOfWeek?: number; // 1-7
|
|
|
|
to?: string;
|
|
toDayOfWeek?: number; // 1-7
|
|
|
|
timezone?: string;
|
|
}
|
|
|
|
interface ParsedTime {
|
|
dayOfWeek?: number; // 1-7
|
|
h?: number; // 0-23
|
|
m?: number; // 0-59
|
|
s?: number; // 0-59
|
|
}
|
|
|
|
export function calculateTimesWithin(cfg: TimeRegionConfig, tRange: TimeRange): AbsoluteTimeRange[] {
|
|
if (!(cfg.fromDayOfWeek || cfg.from) && !(cfg.toDayOfWeek || cfg.to)) {
|
|
return [];
|
|
}
|
|
|
|
// So we can mutate
|
|
const timeRegion = { ...cfg };
|
|
|
|
if (timeRegion.from && !timeRegion.to) {
|
|
timeRegion.to = timeRegion.from;
|
|
}
|
|
|
|
if (!timeRegion.from && timeRegion.to) {
|
|
timeRegion.from = timeRegion.to;
|
|
}
|
|
|
|
const hRange = {
|
|
from: parseTimeOfDay(timeRegion.from),
|
|
to: parseTimeOfDay(timeRegion.to),
|
|
};
|
|
|
|
if (!timeRegion.fromDayOfWeek && timeRegion.toDayOfWeek) {
|
|
timeRegion.fromDayOfWeek = timeRegion.toDayOfWeek;
|
|
}
|
|
|
|
if (!timeRegion.toDayOfWeek && timeRegion.fromDayOfWeek) {
|
|
timeRegion.toDayOfWeek = timeRegion.fromDayOfWeek;
|
|
}
|
|
|
|
if (timeRegion.fromDayOfWeek) {
|
|
hRange.from.dayOfWeek = Number(timeRegion.fromDayOfWeek);
|
|
}
|
|
|
|
if (timeRegion.toDayOfWeek) {
|
|
hRange.to.dayOfWeek = Number(timeRegion.toDayOfWeek);
|
|
}
|
|
|
|
if (hRange.from.dayOfWeek && hRange.from.h == null && hRange.from.m == null) {
|
|
hRange.from.h = 0;
|
|
hRange.from.m = 0;
|
|
hRange.from.s = 0;
|
|
}
|
|
|
|
if (hRange.to.dayOfWeek && hRange.to.h == null && hRange.to.m == null) {
|
|
hRange.to.h = 23;
|
|
hRange.to.m = 59;
|
|
hRange.to.s = 59;
|
|
}
|
|
|
|
if (!hRange.from || !hRange.to) {
|
|
return [];
|
|
}
|
|
|
|
if (hRange.from.h == null) {
|
|
hRange.from.h = 0;
|
|
}
|
|
|
|
if (hRange.to.h == null) {
|
|
hRange.to.h = 23;
|
|
}
|
|
|
|
const regions: AbsoluteTimeRange[] = [];
|
|
|
|
const fromStart = dateTime(tRange.from).utc();
|
|
fromStart.set('hour', 0);
|
|
fromStart.set('minute', 0);
|
|
fromStart.set('second', 0);
|
|
fromStart.set('millisecond', 0);
|
|
fromStart.add(hRange.from.h, 'hours');
|
|
fromStart.add(hRange.from.m, 'minutes');
|
|
fromStart.add(hRange.from.s, 'seconds');
|
|
|
|
while (fromStart.unix() <= tRange.to.unix()) {
|
|
while (hRange.from.dayOfWeek && hRange.from.dayOfWeek !== fromStart.isoWeekday()) {
|
|
fromStart.add(24, 'hours');
|
|
}
|
|
|
|
if (fromStart.unix() > tRange.to.unix()) {
|
|
break;
|
|
}
|
|
|
|
const fromEnd = dateTime(fromStart).utc();
|
|
|
|
if (fromEnd.hour) {
|
|
if (hRange.from.h <= hRange.to.h) {
|
|
fromEnd.add(hRange.to.h - hRange.from.h, 'hours');
|
|
} else if (hRange.from.h > hRange.to.h) {
|
|
while (fromEnd.hour() !== hRange.to.h) {
|
|
fromEnd.add(1, 'hours');
|
|
}
|
|
} else {
|
|
fromEnd.add(24 - hRange.from.h, 'hours');
|
|
|
|
while (fromEnd.hour() !== hRange.to.h) {
|
|
fromEnd.add(1, 'hours');
|
|
}
|
|
}
|
|
}
|
|
|
|
fromEnd.set('minute', hRange.to.m ?? 0);
|
|
fromEnd.set('second', hRange.to.s ?? 0);
|
|
|
|
while (hRange.to.dayOfWeek && hRange.to.dayOfWeek !== fromEnd.isoWeekday()) {
|
|
fromEnd.add(24, 'hours');
|
|
}
|
|
|
|
const outsideRange =
|
|
(fromStart.unix() < tRange.from.unix() && fromEnd.unix() < tRange.from.unix()) ||
|
|
(fromStart.unix() > tRange.to.unix() && fromEnd.unix() > tRange.to.unix());
|
|
|
|
if (!outsideRange) {
|
|
regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() });
|
|
}
|
|
|
|
fromStart.add(24, 'hours');
|
|
}
|
|
|
|
return regions;
|
|
}
|
|
|
|
export function parseTimeOfDay(str?: string): ParsedTime {
|
|
const result: ParsedTime = {};
|
|
if (!str?.length) {
|
|
return result;
|
|
}
|
|
|
|
const match = str.split(':');
|
|
if (!match?.length) {
|
|
return result;
|
|
}
|
|
|
|
result.h = Math.min(23, Math.max(0, Number(match[0])));
|
|
if (match.length > 1) {
|
|
result.m = Math.min(60, Math.max(0, Number(match[1])));
|
|
if (match.length > 2) {
|
|
result.s = Math.min(60, Math.max(0, Number(match[2])));
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function formatTimeOfDayString(t?: ParsedTime): string {
|
|
if (!t || (t.h == null && t.m == null && t.s == null)) {
|
|
return '';
|
|
}
|
|
|
|
let str = String(t.h ?? 0).padStart(2, '0') + ':' + String(t.m ?? 0).padStart(2, '0');
|
|
if (t.s != null) {
|
|
str += String(t.s ?? 0).padStart(2, '0');
|
|
}
|
|
|
|
return str;
|
|
}
|