formatDistanceStrict.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. "use strict";
  2. exports.formatDistanceStrict = formatDistanceStrict;
  3. var _index = require("./_lib/defaultLocale.js");
  4. var _index2 = require("./_lib/defaultOptions.js");
  5. var _index3 = require("./_lib/getRoundingMethod.js");
  6. var _index4 = require("./_lib/getTimezoneOffsetInMilliseconds.js");
  7. var _index5 = require("./compareAsc.js");
  8. var _index6 = require("./constants.js");
  9. var _index7 = require("./toDate.js");
  10. /**
  11. * The {@link formatDistanceStrict} function options.
  12. */
  13. /**
  14. * The unit used to format the distance in {@link formatDistanceStrict}.
  15. */
  16. /**
  17. * @name formatDistanceStrict
  18. * @category Common Helpers
  19. * @summary Return the distance between the given dates in words.
  20. *
  21. * @description
  22. * Return the distance between the given dates in words, using strict units.
  23. * This is like `formatDistance`, but does not use helpers like 'almost', 'over',
  24. * 'less than' and the like.
  25. *
  26. * | Distance between dates | Result |
  27. * |------------------------|---------------------|
  28. * | 0 ... 59 secs | [0..59] seconds |
  29. * | 1 ... 59 mins | [1..59] minutes |
  30. * | 1 ... 23 hrs | [1..23] hours |
  31. * | 1 ... 29 days | [1..29] days |
  32. * | 1 ... 11 months | [1..11] months |
  33. * | 1 ... N years | [1..N] years |
  34. *
  35. * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
  36. *
  37. * @param date - The date
  38. * @param baseDate - The date to compare with
  39. * @param options - An object with options
  40. *
  41. * @returns The distance in words
  42. *
  43. * @throws `date` must not be Invalid Date
  44. * @throws `baseDate` must not be Invalid Date
  45. * @throws `options.unit` must be 'second', 'minute', 'hour', 'day', 'month' or 'year'
  46. * @throws `options.locale` must contain `formatDistance` property
  47. *
  48. * @example
  49. * // What is the distance between 2 July 2014 and 1 January 2015?
  50. * const result = formatDistanceStrict(new Date(2014, 6, 2), new Date(2015, 0, 2))
  51. * //=> '6 months'
  52. *
  53. * @example
  54. * // What is the distance between 1 January 2015 00:00:15
  55. * // and 1 January 2015 00:00:00?
  56. * const result = formatDistanceStrict(
  57. * new Date(2015, 0, 1, 0, 0, 15),
  58. * new Date(2015, 0, 1, 0, 0, 0)
  59. * )
  60. * //=> '15 seconds'
  61. *
  62. * @example
  63. * // What is the distance from 1 January 2016
  64. * // to 1 January 2015, with a suffix?
  65. * const result = formatDistanceStrict(new Date(2015, 0, 1), new Date(2016, 0, 1), {
  66. * addSuffix: true
  67. * })
  68. * //=> '1 year ago'
  69. *
  70. * @example
  71. * // What is the distance from 1 January 2016
  72. * // to 1 January 2015, in minutes?
  73. * const result = formatDistanceStrict(new Date(2016, 0, 1), new Date(2015, 0, 1), {
  74. * unit: 'minute'
  75. * })
  76. * //=> '525600 minutes'
  77. *
  78. * @example
  79. * // What is the distance from 1 January 2015
  80. * // to 28 January 2015, in months, rounded up?
  81. * const result = formatDistanceStrict(new Date(2015, 0, 28), new Date(2015, 0, 1), {
  82. * unit: 'month',
  83. * roundingMethod: 'ceil'
  84. * })
  85. * //=> '1 month'
  86. *
  87. * @example
  88. * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?
  89. * import { eoLocale } from 'date-fns/locale/eo'
  90. * const result = formatDistanceStrict(new Date(2016, 7, 1), new Date(2015, 0, 1), {
  91. * locale: eoLocale
  92. * })
  93. * //=> '1 jaro'
  94. */
  95. function formatDistanceStrict(date, baseDate, options) {
  96. const defaultOptions = (0, _index2.getDefaultOptions)();
  97. const locale =
  98. options?.locale ?? defaultOptions.locale ?? _index.defaultLocale;
  99. const comparison = (0, _index5.compareAsc)(date, baseDate);
  100. if (isNaN(comparison)) {
  101. throw new RangeError("Invalid time value");
  102. }
  103. const localizeOptions = Object.assign({}, options, {
  104. addSuffix: options?.addSuffix,
  105. comparison: comparison,
  106. });
  107. let dateLeft;
  108. let dateRight;
  109. if (comparison > 0) {
  110. dateLeft = (0, _index7.toDate)(baseDate);
  111. dateRight = (0, _index7.toDate)(date);
  112. } else {
  113. dateLeft = (0, _index7.toDate)(date);
  114. dateRight = (0, _index7.toDate)(baseDate);
  115. }
  116. const roundingMethod = (0, _index3.getRoundingMethod)(
  117. options?.roundingMethod ?? "round",
  118. );
  119. const milliseconds = dateRight.getTime() - dateLeft.getTime();
  120. const minutes = milliseconds / _index6.millisecondsInMinute;
  121. const timezoneOffset =
  122. (0, _index4.getTimezoneOffsetInMilliseconds)(dateRight) -
  123. (0, _index4.getTimezoneOffsetInMilliseconds)(dateLeft);
  124. // Use DST-normalized difference in minutes for years, months and days;
  125. // use regular difference in minutes for hours, minutes and seconds.
  126. const dstNormalizedMinutes =
  127. (milliseconds - timezoneOffset) / _index6.millisecondsInMinute;
  128. const defaultUnit = options?.unit;
  129. let unit;
  130. if (!defaultUnit) {
  131. if (minutes < 1) {
  132. unit = "second";
  133. } else if (minutes < 60) {
  134. unit = "minute";
  135. } else if (minutes < _index6.minutesInDay) {
  136. unit = "hour";
  137. } else if (dstNormalizedMinutes < _index6.minutesInMonth) {
  138. unit = "day";
  139. } else if (dstNormalizedMinutes < _index6.minutesInYear) {
  140. unit = "month";
  141. } else {
  142. unit = "year";
  143. }
  144. } else {
  145. unit = defaultUnit;
  146. }
  147. // 0 up to 60 seconds
  148. if (unit === "second") {
  149. const seconds = roundingMethod(milliseconds / 1000);
  150. return locale.formatDistance("xSeconds", seconds, localizeOptions);
  151. // 1 up to 60 mins
  152. } else if (unit === "minute") {
  153. const roundedMinutes = roundingMethod(minutes);
  154. return locale.formatDistance("xMinutes", roundedMinutes, localizeOptions);
  155. // 1 up to 24 hours
  156. } else if (unit === "hour") {
  157. const hours = roundingMethod(minutes / 60);
  158. return locale.formatDistance("xHours", hours, localizeOptions);
  159. // 1 up to 30 days
  160. } else if (unit === "day") {
  161. const days = roundingMethod(dstNormalizedMinutes / _index6.minutesInDay);
  162. return locale.formatDistance("xDays", days, localizeOptions);
  163. // 1 up to 12 months
  164. } else if (unit === "month") {
  165. const months = roundingMethod(
  166. dstNormalizedMinutes / _index6.minutesInMonth,
  167. );
  168. return months === 12 && defaultUnit !== "month"
  169. ? locale.formatDistance("xYears", 1, localizeOptions)
  170. : locale.formatDistance("xMonths", months, localizeOptions);
  171. // 1 year up to max Date
  172. } else {
  173. const years = roundingMethod(dstNormalizedMinutes / _index6.minutesInYear);
  174. return locale.formatDistance("xYears", years, localizeOptions);
  175. }
  176. }