1 | /**
|
2 | * This package exports a single function, {@link timeAgo},
|
3 | * which describes the time elapsed between a given date and the current date
|
4 | * in a human readable format (for example, `10 minutes ago`, `in 3 seconds`).
|
5 | *
|
6 | * @packageDocumentation
|
7 | */
|
8 |
|
9 | /**
|
10 | * `timeAgo` returns a string describing the time elapsed between
|
11 | * a given date and the current time at which the function is called.
|
12 | *
|
13 | * @remarks
|
14 | * `timeAgo` only supports the `en_US` locale.
|
15 | *
|
16 | * The following table describes `timeAgo`'s output.
|
17 | *
|
18 | * ```
|
19 | * | Time elapsed | Past output | Future output |
|
20 | * | --------------------- | ----------------- | ---------------- |
|
21 | * | < 1 second | `just now` | `just now` |
|
22 | * | < 1 minute | `N second(s) ago` | `in N second(s)` |
|
23 | * | < 1 hour | `N minute(s) ago` | `in N minute(s)` |
|
24 | * | < 1 day | `N hour(s) ago` | `in N hour(s)` |
|
25 | * | < 1 month (30.5 days) | `N day(s) ago` | `in N day(s)` |
|
26 | * | < 1 year (365 days) | `N month(s) ago` | `in N month(s)` |
|
27 | * | > 1 year | `N year(s) ago` | `in N year(s)` |
|
28 | * ```
|
29 | *
|
30 | * @example
|
31 | * Basic usage:
|
32 | *
|
33 | * ```typescript
|
34 | * import { timeAgo } from 'short-time-ago';
|
35 | *
|
36 | * const myDate = new Date();
|
37 | * const description = timeAgo(myDate);
|
38 | *
|
39 | * // Output: `just now`.
|
40 | * console.log(description);
|
41 | * ```
|
42 | *
|
43 | * @example
|
44 | * Specifying a custom current date with the `now` parameter:
|
45 | *
|
46 | * ```typescript
|
47 | * import { timeAgo } from 'short-time-ago';
|
48 | *
|
49 | * const myDate = new Date('2019-01-01T00:00:00.000Z');
|
50 | * const now = new Date('2019-01-01T00:01:00.000Z');
|
51 | * const description = timeAgo(myDate, now);
|
52 | *
|
53 | * // Output: `1 minute ago`.
|
54 | * console.log(description);
|
55 | * ```
|
56 | *
|
57 | * ```typescript
|
58 | * import { timeAgo } from 'short-time-ago';
|
59 | *
|
60 | * const myDate = new Date('2019-01-02T00:00:00.000Z');
|
61 | * const now = new Date('2019-01-01T00:00:00.000Z');
|
62 | * const description = timeAgo(myDate, now);
|
63 | *
|
64 | * // Output: `in 1 day`.
|
65 | * console.log(description);
|
66 | * ```
|
67 | *
|
68 | * @param date - a {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date | Date}
|
69 | * @param now - the current date (optional, defaults to `new Date()`)
|
70 | */
|
71 | export function timeAgo(date: Date, now?: Date): string {
|
72 | const units = [
|
73 | ['year', 365 * 24 * 60 * 60 * 1000],
|
74 | ['month', 30.5 * 24 * 60 * 60 * 1000],
|
75 | ['day', 24 * 60 * 60 * 1000],
|
76 | ['hour', 60 * 60 * 1000],
|
77 | ['minute', 60 * 1000],
|
78 | ['second', 1000],
|
79 | ] as const;
|
80 |
|
81 | const diff = (now || new Date()).getTime() - date.getTime();
|
82 | const elapsed = Math.abs(diff);
|
83 |
|
84 | for (const [name, size] of units) {
|
85 | const value = Math.floor(elapsed / size);
|
86 | if (value > 0) {
|
87 | const plural = value > 1 ? 's' : '';
|
88 | const description = `${value} ${name}${plural}`;
|
89 | return diff > 0 ? `${description} ago` : `in ${description}`;
|
90 | }
|
91 | }
|
92 |
|
93 | return 'just now';
|
94 | }
|