UNPKG

2.89 kBJavaScriptView Raw
1import { defaultLocale } from "./_lib/defaultLocale.js";
2import { getDefaultOptions } from "./_lib/defaultOptions.js";
3import { normalizeDates } from "./_lib/normalizeDates.js";
4import { differenceInCalendarDays } from "./differenceInCalendarDays.js";
5import { format } from "./format.js";
6
7/**
8 * The {@link formatRelative} function options.
9 */
10
11/**
12 * @name formatRelative
13 * @category Common Helpers
14 * @summary Represent the date in words relative to the given base date.
15 *
16 * @description
17 * Represent the date in words relative to the given base date.
18 *
19 * | Distance to the base date | Result |
20 * |---------------------------|---------------------------|
21 * | Previous 6 days | last Sunday at 04:30 AM |
22 * | Last day | yesterday at 04:30 AM |
23 * | Same day | today at 04:30 AM |
24 * | Next day | tomorrow at 04:30 AM |
25 * | Next 6 days | Sunday at 04:30 AM |
26 * | Other | 12/31/2017 |
27 *
28 * @param date - The date to format
29 * @param baseDate - The date to compare with
30 * @param options - An object with options
31 *
32 * @returns The date in words
33 *
34 * @throws `date` must not be Invalid Date
35 * @throws `baseDate` must not be Invalid Date
36 * @throws `options.locale` must contain `localize` property
37 * @throws `options.locale` must contain `formatLong` property
38 * @throws `options.locale` must contain `formatRelative` property
39 *
40 * @example
41 * // Represent the date of 6 days ago in words relative to the given base date. In this example, today is Wednesday
42 * const result = formatRelative(subDays(new Date(), 6), new Date())
43 * //=> "last Thursday at 12:45 AM"
44 */
45export function formatRelative(date, baseDate, options) {
46 const [date_, baseDate_] = normalizeDates(options?.in, date, baseDate);
47
48 const defaultOptions = getDefaultOptions();
49 const locale = options?.locale ?? defaultOptions.locale ?? defaultLocale;
50 const weekStartsOn =
51 options?.weekStartsOn ??
52 options?.locale?.options?.weekStartsOn ??
53 defaultOptions.weekStartsOn ??
54 defaultOptions.locale?.options?.weekStartsOn ??
55 0;
56
57 const diff = differenceInCalendarDays(date_, baseDate_);
58
59 if (isNaN(diff)) {
60 throw new RangeError("Invalid time value");
61 }
62
63 let token;
64 if (diff < -6) {
65 token = "other";
66 } else if (diff < -1) {
67 token = "lastWeek";
68 } else if (diff < 0) {
69 token = "yesterday";
70 } else if (diff < 1) {
71 token = "today";
72 } else if (diff < 2) {
73 token = "tomorrow";
74 } else if (diff < 7) {
75 token = "nextWeek";
76 } else {
77 token = "other";
78 }
79
80 const formatStr = locale.formatRelative(token, date_, baseDate_, {
81 locale,
82 weekStartsOn,
83 });
84 return format(date_, formatStr, { locale, weekStartsOn });
85}
86
87// Fallback for modularized imports:
88export default formatRelative;