Add custom selectUnit, use in relativeTime function (#14008)

This commit is contained in:
Michael Varrieur 2022-10-10 10:26:02 -04:00 committed by GitHub
parent 08279f35cf
commit 0c800344d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 12 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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
};

View File

@ -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");
});
});

View File

@ -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