index.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import toDate from "../toDate/index.js";
  2. import requiredArgs from "../_lib/requiredArgs/index.js";
  3. /**
  4. * @name closestTo
  5. * @category Common Helpers
  6. * @summary Return a date from the array closest to the given date.
  7. *
  8. * @description
  9. * Return a date from the array closest to the given date.
  10. *
  11. * ### v2.0.0 breaking changes:
  12. *
  13. * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
  14. *
  15. * - Now, `closestTo` doesn't throw an exception
  16. * when the second argument is not an array, and returns Invalid Date instead.
  17. *
  18. * @param {Date|Number} dateToCompare - the date to compare with
  19. * @param {Date[]|Number[]} datesArray - the array to search
  20. * @returns {Date} the date from the array closest to the given date
  21. * @throws {TypeError} 2 arguments required
  22. *
  23. * @example
  24. * // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030?
  25. * var dateToCompare = new Date(2015, 8, 6)
  26. * var result = closestTo(dateToCompare, [
  27. * new Date(2000, 0, 1),
  28. * new Date(2030, 0, 1)
  29. * ])
  30. * //=> Tue Jan 01 2030 00:00:00
  31. */
  32. export default function closestTo(dirtyDateToCompare, dirtyDatesArray) {
  33. requiredArgs(2, arguments);
  34. var dateToCompare = toDate(dirtyDateToCompare);
  35. if (isNaN(dateToCompare)) {
  36. return new Date(NaN);
  37. }
  38. var timeToCompare = dateToCompare.getTime();
  39. var datesArray; // `dirtyDatesArray` is undefined or null
  40. if (dirtyDatesArray == null) {
  41. datesArray = []; // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method
  42. } else if (typeof dirtyDatesArray.forEach === 'function') {
  43. datesArray = dirtyDatesArray; // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array
  44. } else {
  45. datesArray = Array.prototype.slice.call(dirtyDatesArray);
  46. }
  47. var result;
  48. var minDistance;
  49. datesArray.forEach(function (dirtyDate) {
  50. var currentDate = toDate(dirtyDate);
  51. if (isNaN(currentDate)) {
  52. result = new Date(NaN);
  53. minDistance = NaN;
  54. return;
  55. }
  56. var distance = Math.abs(timeToCompare - currentDate.getTime());
  57. if (result == null || distance < minDistance) {
  58. result = currentDate;
  59. minDistance = distance;
  60. }
  61. });
  62. return result;
  63. }