1import moment from 'moment-timezone';
2
3const rangeUnits: { [unit: string]: number } = {
4  y: 60 * 60 * 24 * 365,
5  w: 60 * 60 * 24 * 7,
6  d: 60 * 60 * 24,
7  h: 60 * 60,
8  m: 60,
9  s: 1,
10};
11
12export function parseRange(rangeText: string): number | null {
13  const rangeRE = new RegExp('^([0-9]+)([ywdhms]+)$');
14  const matches = rangeText.match(rangeRE);
15  if (!matches || matches.length !== 3) {
16    return null;
17  }
18  const value = parseInt(matches[1]);
19  const unit = matches[2];
20  return value * rangeUnits[unit];
21}
22
23export function formatRange(range: number): string {
24  for (const unit of Object.keys(rangeUnits)) {
25    if (range % rangeUnits[unit] === 0) {
26      return range / rangeUnits[unit] + unit;
27    }
28  }
29  return range + 's';
30}
31
32export function parseTime(timeText: string): number {
33  return moment.utc(timeText).valueOf();
34}
35
36export function formatTime(time: number): string {
37  return moment.utc(time).format('YYYY-MM-DD HH:mm:ss');
38}
39
40export const now = (): number => moment().valueOf();
41
42export const humanizeDuration = (milliseconds: number): string => {
43  const sign = milliseconds < 0 ? '-' : '';
44  const unsignedMillis = milliseconds < 0 ? -1 * milliseconds : milliseconds;
45  const duration = moment.duration(unsignedMillis, 'ms');
46  const ms = Math.floor(duration.milliseconds());
47  const s = Math.floor(duration.seconds());
48  const m = Math.floor(duration.minutes());
49  const h = Math.floor(duration.hours());
50  const d = Math.floor(duration.asDays());
51  if (d !== 0) {
52    return `${sign}${d}d ${h}h ${m}m ${s}s`;
53  }
54  if (h !== 0) {
55    return `${sign}${h}h ${m}m ${s}s`;
56  }
57  if (m !== 0) {
58    return `${sign}${m}m ${s}s`;
59  }
60  if (s !== 0) {
61    return `${sign}${s}.${ms}s`;
62  }
63  if (unsignedMillis > 0) {
64    return `${sign}${unsignedMillis.toFixed(3)}ms`;
65  }
66  return '0s';
67};
68
69export const formatRelative = (startStr: string, end: number): string => {
70  const start = parseTime(startStr);
71  if (start < 0) {
72    return 'Never';
73  }
74  return humanizeDuration(end - start);
75};
76