|
1 | 1 | const calculateDelta = (now, date) => Math.round(Math.abs(now - date) / 1000)
|
2 | 2 |
|
| 3 | +const minute = 60 |
| 4 | +const hour = minute * 60 |
| 5 | +const day = hour * 24 |
| 6 | +const week = day * 7 |
| 7 | +const month = day * 30 |
| 8 | +const year = day * 365 |
| 9 | + |
3 | 10 | export default function relativeDateFactory (translations) {
|
4 |
| - return function relativeDate (date, now = new Date()) { |
5 |
| - if (!(date instanceof Date)) { |
6 |
| - date = new Date(date) |
| 11 | + const translate = (date, now, translatePhrase, timeValue, rawValue) => { |
| 12 | + let key |
| 13 | + |
| 14 | + if (translatePhrase === 'justNow') { |
| 15 | + key = translatePhrase |
| 16 | + } else if (now >= date) { |
| 17 | + key = `${translatePhrase}Ago` |
| 18 | + } else { |
| 19 | + key = `${translatePhrase}FromNow` |
7 | 20 | }
|
8 | 21 |
|
9 |
| - let delta = null |
| 22 | + const translation = translations[key] |
10 | 23 |
|
11 |
| - const minute = 60 |
12 |
| - const hour = minute * 60 |
13 |
| - const day = hour * 24 |
14 |
| - const week = day * 7 |
15 |
| - const month = day * 30 |
16 |
| - const year = day * 365 |
17 |
| - |
18 |
| - delta = calculateDelta(now, date) |
19 |
| - |
20 |
| - if (delta > day && delta < week) { |
21 |
| - date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0) |
22 |
| - delta = calculateDelta(now, date) |
| 24 | + if (typeof translation === 'function') { |
| 25 | + return translation(timeValue, rawValue) |
23 | 26 | }
|
24 | 27 |
|
25 |
| - const translate = (translatePhrase, timeValue) => { |
26 |
| - let key |
27 |
| - |
28 |
| - if (translatePhrase === 'justNow') { |
29 |
| - key = translatePhrase |
30 |
| - } else if (now >= date) { |
31 |
| - key = `${translatePhrase}Ago` |
32 |
| - } else { |
33 |
| - key = `${translatePhrase}FromNow` |
34 |
| - } |
| 28 | + return translation.replace('{{time}}', timeValue) |
| 29 | + } |
35 | 30 |
|
36 |
| - const translation = translations[key] |
| 31 | + return function relativeDate (date, now = new Date()) { |
| 32 | + if (!(date instanceof Date)) { |
| 33 | + date = new Date(date) |
| 34 | + } |
37 | 35 |
|
38 |
| - if (typeof translation === 'function') { |
39 |
| - return translation(timeValue) |
40 |
| - } |
| 36 | + let delta = calculateDelta(now, date) |
41 | 37 |
|
42 |
| - return translation.replace('{{time}}', timeValue) |
| 38 | + if (delta > day && delta < week) { |
| 39 | + date = new Date( |
| 40 | + date.getFullYear(), |
| 41 | + date.getMonth(), |
| 42 | + date.getDate(), |
| 43 | + 0, |
| 44 | + 0, |
| 45 | + 0 |
| 46 | + ) |
| 47 | + delta = calculateDelta(now, date) |
43 | 48 | }
|
44 | 49 |
|
45 | 50 | switch (false) {
|
46 | 51 | case !(delta < 30):
|
47 |
| - return translate('justNow') |
| 52 | + return translate(date, now, 'justNow', delta, delta) |
48 | 53 |
|
49 | 54 | case !(delta < minute):
|
50 |
| - return translate('seconds', delta) |
| 55 | + return translate(date, now, 'seconds', delta, delta) |
51 | 56 |
|
52 | 57 | case !(delta < 2 * minute):
|
53 |
| - return translate('aMinute') |
| 58 | + return translate(date, now, 'aMinute', 1, delta) |
54 | 59 |
|
55 | 60 | case !(delta < hour):
|
56 |
| - return translate('minutes', Math.floor(delta / minute)) |
| 61 | + return translate( |
| 62 | + date, |
| 63 | + now, |
| 64 | + 'minutes', |
| 65 | + Math.floor(delta / minute), |
| 66 | + delta |
| 67 | + ) |
57 | 68 |
|
58 | 69 | case Math.floor(delta / hour) !== 1:
|
59 |
| - return translate('anHour') |
| 70 | + return translate( |
| 71 | + date, |
| 72 | + now, |
| 73 | + 'anHour', |
| 74 | + Math.floor(delta / minute), |
| 75 | + delta |
| 76 | + ) |
60 | 77 |
|
61 | 78 | case !(delta < day):
|
62 |
| - return translate('hours', Math.floor(delta / hour)) |
| 79 | + return translate(date, now, 'hours', Math.floor(delta / hour), delta) |
63 | 80 |
|
64 | 81 | case !(delta < day * 2):
|
65 |
| - return translate('aDay') |
| 82 | + return translate(date, now, 'aDay', 1, delta) |
66 | 83 |
|
67 | 84 | case !(delta < week):
|
68 |
| - return translate('days', Math.floor(delta / day)) |
| 85 | + return translate(date, now, 'days', Math.floor(delta / day), delta) |
69 | 86 |
|
70 | 87 | case Math.floor(delta / week) !== 1:
|
71 |
| - return translate('aWeek') |
| 88 | + return translate(date, now, 'aWeek', 1, delta) |
72 | 89 |
|
73 | 90 | case !(delta < month):
|
74 |
| - return translate('weeks', Math.floor(delta / week)) |
| 91 | + return translate(date, now, 'weeks', Math.floor(delta / week), delta) |
75 | 92 |
|
76 | 93 | case Math.floor(delta / month) !== 1:
|
77 |
| - return translate('aMonth') |
| 94 | + return translate(date, now, 'aMonth', 1, delta) |
78 | 95 |
|
79 | 96 | case !(delta < year):
|
80 |
| - return translate('months', Math.floor(delta / month)) |
| 97 | + return translate(date, now, 'months', Math.floor(delta / month), delta) |
81 | 98 |
|
82 | 99 | case Math.floor(delta / year) !== 1:
|
83 |
| - return translate('aYear') |
| 100 | + return translate(date, now, 'aYear', 1, delta) |
84 | 101 |
|
85 | 102 | default:
|
86 |
| - return translate('overAYear') |
| 103 | + return translate( |
| 104 | + date, |
| 105 | + now, |
| 106 | + 'overAYear', |
| 107 | + Math.floor(delta / year), |
| 108 | + delta |
| 109 | + ) |
87 | 110 | }
|
88 | 111 | }
|
89 | 112 | }
|
0 commit comments