index.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. * @param {Date | Number} dateToCompare - the date to compare with
  12. * @param {Array<Date> | Array<number>} datesArray - the array to search
  13. * @returns {Date | undefined} the date from the array closest to the given date or undefined if no valid value is given
  14. * @throws {TypeError} 2 arguments required
  15. *
  16. * @example
  17. * // Which date is closer to 6 September 2015: 1 January 2000 or 1 January 2030?
  18. * const dateToCompare = new Date(2015, 8, 6)
  19. * const result = closestTo(dateToCompare, [
  20. * new Date(2000, 0, 1),
  21. * new Date(2030, 0, 1)
  22. * ])
  23. * //=> Tue Jan 01 2030 00:00:00
  24. */
  25. export default function closestTo(dirtyDateToCompare, dirtyDatesArray) {
  26. requiredArgs(2, arguments);
  27. var dateToCompare = toDate(dirtyDateToCompare);
  28. if (isNaN(Number(dateToCompare))) return new Date(NaN);
  29. var timeToCompare = dateToCompare.getTime();
  30. var datesArray;
  31. // `dirtyDatesArray` is undefined or null
  32. if (dirtyDatesArray == null) {
  33. datesArray = [];
  34. // `dirtyDatesArray` is Array, Set or Map, or object with custom `forEach` method
  35. } else if (typeof dirtyDatesArray.forEach === 'function') {
  36. datesArray = dirtyDatesArray;
  37. // If `dirtyDatesArray` is Array-like Object, convert to Array. Otherwise, make it empty Array
  38. } else {
  39. datesArray = Array.prototype.slice.call(dirtyDatesArray);
  40. }
  41. var result;
  42. var minDistance;
  43. datesArray.forEach(function (dirtyDate) {
  44. var currentDate = toDate(dirtyDate);
  45. if (isNaN(Number(currentDate))) {
  46. result = new Date(NaN);
  47. minDistance = NaN;
  48. return;
  49. }
  50. var distance = Math.abs(timeToCompare - currentDate.getTime());
  51. if (result == null || distance < Number(minDistance)) {
  52. result = currentDate;
  53. minDistance = distance;
  54. }
  55. });
  56. return result;
  57. }