• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const calculateDelta = (now, date) => Math.round(Math.abs(now - date) / 1000)
2
3export default function relativeDateFactory (translations) {
4  return function relativeDate (date, now = new Date()) {
5    if (!(date instanceof Date)) {
6      date = new Date(date)
7    }
8
9    let delta = null
10
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)
23    }
24
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      }
35
36      const translation = translations[key]
37
38      if (typeof translation === 'function') {
39        return translation(timeValue)
40      }
41
42      return translation.replace('{{time}}', timeValue)
43    }
44
45    switch (false) {
46      case !(delta < 30):
47        return translate('justNow')
48
49      case !(delta < minute):
50        return translate('seconds', delta)
51
52      case !(delta < 2 * minute):
53        return translate('aMinute')
54
55      case !(delta < hour):
56        return translate('minutes', Math.floor(delta / minute))
57
58      case Math.floor(delta / hour) !== 1:
59        return translate('anHour')
60
61      case !(delta < day):
62        return translate('hours', Math.floor(delta / hour))
63
64      case !(delta < day * 2):
65        return translate('aDay')
66
67      case !(delta < week):
68        return translate('days', Math.floor(delta / day))
69
70      case Math.floor(delta / week) !== 1:
71        return translate('aWeek')
72
73      case !(delta < month):
74        return translate('weeks', Math.floor(delta / week))
75
76      case Math.floor(delta / month) !== 1:
77        return translate('aMonth')
78
79      case !(delta < year):
80        return translate('months', Math.floor(delta / month))
81
82      case Math.floor(delta / year) !== 1:
83        return translate('aYear')
84
85      default:
86        return translate('overAYear')
87    }
88  }
89}
90