Skip to content

packages/core/src/features/viz/lib/utc-labels.ts

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

1 /** Locale used for compact UTC tick text. See {@link utcTickLabels}. */
2 export interface UTCTickLabelOptions {
3   /** BCP 47 locale, default en-US. Calendar is always Gregorian; time zone is UTC. */
4   readonly locale?: string;
5 }
6 /**
7  * Creates compact labels with calendar context retained on every tick.
8  * @param values - At most 100 safe integer epoch milliseconds within Date range, in any order.
9  * @param options - Explicit locale; default en-US.
10  * @returns Frozen labels in input order. No geometry or scale state changes. See {@link UTCTickLabelOptions}.
11  */
12 export function utcTickLabels(values: readonly number[], options: UTCTickLabelOptions = {}): readonly string[] {
13   if (!Array.isArray(values) || values.length > 100 || values.some(v => !Number.isSafeInteger(v) || Math.abs(v) > 8_640_000_000_000_000))
14     throw new RangeError("utcTickLabels requires at most 100 integer timestamps within Date range.");
15   const dates = values.map(value => new Date(value));
16   const midnight = (date: Date) => date.getUTCHours() === 0 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0 && date.getUTCMilliseconds() === 0;
17   const months = dates.every(date => midnight(date) && date.getUTCDate() === 1);
18   const years = months && dates.every(date => date.getUTCMonth() === 0);
19   const days = dates.every(midnight);
20   const milliseconds = dates.some(date => date.getUTCMilliseconds() !== 0);
21   const seconds = milliseconds || dates.some(date => date.getUTCSeconds() !== 0);
22   const formatter = new Intl.DateTimeFormat(options.locale ?? "en-US", {
23     timeZone: "UTC", calendar: "gregory", year: "numeric",
24     ...(years ? {} : { month: "short" as const }),
25     ...(months ? {} : { day: "numeric" as const }),
26     ...(days ? {} : { hour: "2-digit" as const, minute: "2-digit" as const, hourCycle: "h23" as const }),
27     ...(seconds ? { second: "2-digit" as const } : {}),
28     ...(milliseconds ? { fractionalSecondDigits: 3 as const } : {}),
29     ...(dates.some(date => date.getUTCFullYear() <= 0) ? { era: "short" as const } : {}),
30   });
31   return Object.freeze(dates.map(date => formatter.format(date)));
32 }
33 

Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.