index.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. var compareDesc = require('../compare_desc/index.js')
  2. var parse = require('../parse/index.js')
  3. var differenceInSeconds = require('../difference_in_seconds/index.js')
  4. var enLocale = require('../locale/en/index.js')
  5. var MINUTES_IN_DAY = 1440
  6. var MINUTES_IN_MONTH = 43200
  7. var MINUTES_IN_YEAR = 525600
  8. /**
  9. * @category Common Helpers
  10. * @summary Return the distance between the given dates in words.
  11. *
  12. * @description
  13. * Return the distance between the given dates in words, using strict units.
  14. * This is like `distanceInWords`, but does not use helpers like 'almost', 'over',
  15. * 'less than' and the like.
  16. *
  17. * | Distance between dates | Result |
  18. * |------------------------|---------------------|
  19. * | 0 ... 59 secs | [0..59] seconds |
  20. * | 1 ... 59 mins | [1..59] minutes |
  21. * | 1 ... 23 hrs | [1..23] hours |
  22. * | 1 ... 29 days | [1..29] days |
  23. * | 1 ... 11 months | [1..11] months |
  24. * | 1 ... N years | [1..N] years |
  25. *
  26. * @param {Date|String|Number} dateToCompare - the date to compare with
  27. * @param {Date|String|Number} date - the other date
  28. * @param {Object} [options] - the object with options
  29. * @param {Boolean} [options.addSuffix=false] - result indicates if the second date is earlier or later than the first
  30. * @param {'s'|'m'|'h'|'d'|'M'|'Y'} [options.unit] - if specified, will force a unit
  31. * @param {'floor'|'ceil'|'round'} [options.partialMethod='floor'] - which way to round partial units
  32. * @param {Object} [options.locale=enLocale] - the locale object
  33. * @returns {String} the distance in words
  34. *
  35. * @example
  36. * // What is the distance between 2 July 2014 and 1 January 2015?
  37. * var result = distanceInWordsStrict(
  38. * new Date(2014, 6, 2),
  39. * new Date(2015, 0, 2)
  40. * )
  41. * //=> '6 months'
  42. *
  43. * @example
  44. * // What is the distance between 1 January 2015 00:00:15
  45. * // and 1 January 2015 00:00:00?
  46. * var result = distanceInWordsStrict(
  47. * new Date(2015, 0, 1, 0, 0, 15),
  48. * new Date(2015, 0, 1, 0, 0, 0),
  49. * )
  50. * //=> '15 seconds'
  51. *
  52. * @example
  53. * // What is the distance from 1 January 2016
  54. * // to 1 January 2015, with a suffix?
  55. * var result = distanceInWordsStrict(
  56. * new Date(2016, 0, 1),
  57. * new Date(2015, 0, 1),
  58. * {addSuffix: true}
  59. * )
  60. * //=> '1 year ago'
  61. *
  62. * @example
  63. * // What is the distance from 1 January 2016
  64. * // to 1 January 2015, in minutes?
  65. * var result = distanceInWordsStrict(
  66. * new Date(2016, 0, 1),
  67. * new Date(2015, 0, 1),
  68. * {unit: 'm'}
  69. * )
  70. * //=> '525600 minutes'
  71. *
  72. * @example
  73. * // What is the distance from 1 January 2016
  74. * // to 28 January 2015, in months, rounded up?
  75. * var result = distanceInWordsStrict(
  76. * new Date(2015, 0, 28),
  77. * new Date(2015, 0, 1),
  78. * {unit: 'M', partialMethod: 'ceil'}
  79. * )
  80. * //=> '1 month'
  81. *
  82. * @example
  83. * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
  84. * var eoLocale = require('date-fns/locale/eo')
  85. * var result = distanceInWordsStrict(
  86. * new Date(2016, 7, 1),
  87. * new Date(2015, 0, 1),
  88. * {locale: eoLocale}
  89. * )
  90. * //=> '1 jaro'
  91. */
  92. function distanceInWordsStrict (dirtyDateToCompare, dirtyDate, dirtyOptions) {
  93. var options = dirtyOptions || {}
  94. var comparison = compareDesc(dirtyDateToCompare, dirtyDate)
  95. var locale = options.locale
  96. var localize = enLocale.distanceInWords.localize
  97. if (locale && locale.distanceInWords && locale.distanceInWords.localize) {
  98. localize = locale.distanceInWords.localize
  99. }
  100. var localizeOptions = {
  101. addSuffix: Boolean(options.addSuffix),
  102. comparison: comparison
  103. }
  104. var dateLeft, dateRight
  105. if (comparison > 0) {
  106. dateLeft = parse(dirtyDateToCompare)
  107. dateRight = parse(dirtyDate)
  108. } else {
  109. dateLeft = parse(dirtyDate)
  110. dateRight = parse(dirtyDateToCompare)
  111. }
  112. var unit
  113. var mathPartial = Math[options.partialMethod ? String(options.partialMethod) : 'floor']
  114. var seconds = differenceInSeconds(dateRight, dateLeft)
  115. var offset = dateRight.getTimezoneOffset() - dateLeft.getTimezoneOffset()
  116. var minutes = mathPartial(seconds / 60) - offset
  117. var hours, days, months, years
  118. if (options.unit) {
  119. unit = String(options.unit)
  120. } else {
  121. if (minutes < 1) {
  122. unit = 's'
  123. } else if (minutes < 60) {
  124. unit = 'm'
  125. } else if (minutes < MINUTES_IN_DAY) {
  126. unit = 'h'
  127. } else if (minutes < MINUTES_IN_MONTH) {
  128. unit = 'd'
  129. } else if (minutes < MINUTES_IN_YEAR) {
  130. unit = 'M'
  131. } else {
  132. unit = 'Y'
  133. }
  134. }
  135. // 0 up to 60 seconds
  136. if (unit === 's') {
  137. return localize('xSeconds', seconds, localizeOptions)
  138. // 1 up to 60 mins
  139. } else if (unit === 'm') {
  140. return localize('xMinutes', minutes, localizeOptions)
  141. // 1 up to 24 hours
  142. } else if (unit === 'h') {
  143. hours = mathPartial(minutes / 60)
  144. return localize('xHours', hours, localizeOptions)
  145. // 1 up to 30 days
  146. } else if (unit === 'd') {
  147. days = mathPartial(minutes / MINUTES_IN_DAY)
  148. return localize('xDays', days, localizeOptions)
  149. // 1 up to 12 months
  150. } else if (unit === 'M') {
  151. months = mathPartial(minutes / MINUTES_IN_MONTH)
  152. return localize('xMonths', months, localizeOptions)
  153. // 1 year up to max Date
  154. } else if (unit === 'Y') {
  155. years = mathPartial(minutes / MINUTES_IN_YEAR)
  156. return localize('xYears', years, localizeOptions)
  157. }
  158. throw new Error('Unknown unit: ' + unit)
  159. }
  160. module.exports = distanceInWordsStrict