bbovenzi commented on code in PR #72350:
URL: https://github.com/apache/airflow/pull/72350#discussion_r3915428711
##########
airflow-core/src/airflow/ui/src/utils/datetimeUtils.ts:
##########
@@ -139,12 +268,58 @@ export const formatDate = (
return dayjs(date).tz(timezone).format(format);
};
-export const getRelativeTime = (date: string | null | undefined): string => {
- if (date === null || date === "" || date === undefined) {
+// Ordered largest first so the first unit the difference reaches wins: "45
minutes ago" rather than
+// "2700 seconds ago". Months and years use the mean Gregorian lengths CLDR
assumes for relative
+// phrasing. Anything under a minute falls through to seconds.
+const RELATIVE_TIME_UNITS: Array<{ seconds: number; unit:
Intl.RelativeTimeFormatUnit }> = [
+ { seconds: 31_557_600, unit: "year" },
+ { seconds: 2_629_800, unit: "month" },
+ { seconds: SECONDS_PER_DAY * 7, unit: "week" },
+ { seconds: SECONDS_PER_DAY, unit: "day" },
+ { seconds: SECONDS_PER_HOUR, unit: "hour" },
+ { seconds: SECONDS_PER_MINUTE, unit: "minute" },
+ { seconds: 1, unit: "second" },
+];
+
+const RELATIVE_TIME_FALLBACK_UNIT = { seconds: 1, unit: "second" } as const;
+
+const relativeTimeFormatters = new Map<string, Intl.RelativeTimeFormat>();
+
+const getRelativeTimeFormatter = (locale: string): Intl.RelativeTimeFormat => {
+ const cached = relativeTimeFormatters.get(locale);
+
+ if (cached !== undefined) {
+ return cached;
+ }
+
+ const options: Intl.RelativeTimeFormatOptions = { numeric: "auto" };
+ let formatter: Intl.RelativeTimeFormat;
+
+ try {
+ formatter = new Intl.RelativeTimeFormat(locale, options);
+ } catch {
+ formatter = new Intl.RelativeTimeFormat(DEFAULT_LOCALE, options);
+ }
+
+ relativeTimeFormatters.set(locale, formatter);
+
+ return formatter;
+};
+
+export const getRelativeTime = (
+ date: string | null | undefined,
+ locale: string = i18n.language || DEFAULT_LOCALE,
+): string => {
+ if (date === null || date === "" || date === undefined ||
!dayjs(date).isValid()) {
return "";
}
- return dayjs(date).fromNow();
+ const elapsed = dayjs(date).diff(dayjs(), "second", true);
+ const magnitude = Math.abs(elapsed);
+ const { seconds, unit } =
+ RELATIVE_TIME_UNITS.find((candidate) => magnitude >= candidate.seconds) ??
RELATIVE_TIME_FALLBACK_UNIT;
+
+ return getRelativeTimeFormatter(locale).format(Math.round(elapsed /
seconds), unit);
Review Comment:
Updated.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]