|  | 
| 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