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