Add custom selectUnit, use in relativeTime function (#14008)
This commit is contained in:
parent
08279f35cf
commit
0c800344d2
|
@ -43,7 +43,6 @@
|
|||
"@formatjs/intl-numberformat": "^7.2.5",
|
||||
"@formatjs/intl-pluralrules": "^4.1.5",
|
||||
"@formatjs/intl-relativetimeformat": "^9.3.2",
|
||||
"@formatjs/intl-utils": "^3.8.4",
|
||||
"@fullcalendar/common": "5.9.0",
|
||||
"@fullcalendar/core": "5.9.0",
|
||||
"@fullcalendar/daygrid": "5.9.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { selectUnit } from "@formatjs/intl-utils";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { FrontendLocaleData } from "../../data/translation";
|
||||
import { polyfillsLoaded } from "../translations/localize";
|
||||
import { selectUnit } from "../util/select-unit";
|
||||
|
||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
||||
await polyfillsLoaded;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
export type Unit =
|
||||
| "second"
|
||||
| "minute"
|
||||
| "hour"
|
||||
| "day"
|
||||
| "week"
|
||||
| "month"
|
||||
| "quarter"
|
||||
| "year";
|
||||
|
||||
const MS_PER_SECOND = 1e3;
|
||||
const SECS_PER_MIN = 60;
|
||||
const SECS_PER_HOUR = SECS_PER_MIN * 60;
|
||||
const SECS_PER_DAY = SECS_PER_HOUR * 24;
|
||||
const SECS_PER_WEEK = SECS_PER_DAY * 7;
|
||||
|
||||
// Adapted from https://github.com/formatjs/formatjs/blob/186cef62f980ec66252ee232f438a42d0b51b9f9/packages/intl-utils/src/diff.ts
|
||||
export function selectUnit(
|
||||
from: Date | number,
|
||||
to: Date | number = Date.now(),
|
||||
thresholds: Partial<Thresholds> = {}
|
||||
): { value: number; unit: Unit } {
|
||||
const resolvedThresholds: Thresholds = {
|
||||
...DEFAULT_THRESHOLDS,
|
||||
...(thresholds || {}),
|
||||
};
|
||||
|
||||
const secs = (+from - +to) / MS_PER_SECOND;
|
||||
if (Math.abs(secs) < resolvedThresholds.second) {
|
||||
return {
|
||||
value: Math.round(secs),
|
||||
unit: "second",
|
||||
};
|
||||
}
|
||||
|
||||
const mins = secs / SECS_PER_MIN;
|
||||
if (Math.abs(mins) < resolvedThresholds.minute) {
|
||||
return {
|
||||
value: Math.round(mins),
|
||||
unit: "minute",
|
||||
};
|
||||
}
|
||||
|
||||
const hours = secs / SECS_PER_HOUR;
|
||||
if (Math.abs(hours) < resolvedThresholds.hour) {
|
||||
return {
|
||||
value: Math.round(hours),
|
||||
unit: "hour",
|
||||
};
|
||||
}
|
||||
|
||||
const days = secs / SECS_PER_DAY;
|
||||
if (Math.abs(days) < resolvedThresholds.day) {
|
||||
return {
|
||||
value: Math.round(days),
|
||||
unit: "day",
|
||||
};
|
||||
}
|
||||
|
||||
const weeks = secs / SECS_PER_WEEK;
|
||||
if (Math.abs(weeks) < resolvedThresholds.week) {
|
||||
return {
|
||||
value: Math.round(weeks),
|
||||
unit: "week",
|
||||
};
|
||||
}
|
||||
|
||||
const fromDate = new Date(from);
|
||||
const toDate = new Date(to);
|
||||
const years = fromDate.getFullYear() - toDate.getFullYear();
|
||||
const months = years * 12 + fromDate.getMonth() - toDate.getMonth();
|
||||
if (Math.round(Math.abs(months)) < resolvedThresholds.month) {
|
||||
return {
|
||||
value: Math.round(months),
|
||||
unit: "month",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
value: Math.round(years),
|
||||
unit: "year",
|
||||
};
|
||||
}
|
||||
|
||||
type Thresholds = Record<
|
||||
"second" | "minute" | "hour" | "day" | "week" | "month",
|
||||
number
|
||||
>;
|
||||
|
||||
export const DEFAULT_THRESHOLDS: Thresholds = {
|
||||
second: 45, // seconds to minute
|
||||
minute: 45, // minutes to hour
|
||||
hour: 22, // hour to day
|
||||
day: 5, // day to week
|
||||
week: 4, // week to months
|
||||
month: 11, // month to years
|
||||
};
|
|
@ -112,4 +112,12 @@ describe("relativeTime", () => {
|
|||
"1 month"
|
||||
);
|
||||
});
|
||||
|
||||
it("handles a jump between years", () => {
|
||||
const inputdt = new Date("2021-12-29");
|
||||
const compare = new Date("2022-01-01");
|
||||
|
||||
assert.strictEqual(relativeTime(inputdt, locale, compare), "3 days ago");
|
||||
assert.strictEqual(relativeTime(inputdt, locale, compare, false), "3 days");
|
||||
});
|
||||
});
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -1679,15 +1679,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@formatjs/intl-utils@npm:^3.8.4":
|
||||
version: 3.8.4
|
||||
resolution: "@formatjs/intl-utils@npm:3.8.4"
|
||||
dependencies:
|
||||
emojis-list: ^3.0.0
|
||||
checksum: e38a98d391ec68d8abc4bb1824426bd804dfb022ce61be004459faec69f7843ddb3733bae8d0dce4aafbfafad59cb10e67fc21d22d62f68d98251ce0bce8e704
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fullcalendar/common@npm:5.9.0, @fullcalendar/common@npm:~5.9.0":
|
||||
version: 5.9.0
|
||||
resolution: "@fullcalendar/common@npm:5.9.0"
|
||||
|
@ -8982,7 +8973,6 @@ fsevents@^1.2.7:
|
|||
"@formatjs/intl-numberformat": ^7.2.5
|
||||
"@formatjs/intl-pluralrules": ^4.1.5
|
||||
"@formatjs/intl-relativetimeformat": ^9.3.2
|
||||
"@formatjs/intl-utils": ^3.8.4
|
||||
"@fullcalendar/common": 5.9.0
|
||||
"@fullcalendar/core": 5.9.0
|
||||
"@fullcalendar/daygrid": 5.9.0
|
||||
|
|
Loading…
Reference in New Issue