roundToNearestHours.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { getRoundingMethod } from "./_lib/getRoundingMethod.js";
  2. import { constructFrom } from "./constructFrom.js";
  3. import { toDate } from "./toDate.js";
  4. /**
  5. * The {@link roundToNearestHours} function options.
  6. */
  7. /**
  8. * @name roundToNearestHours
  9. * @category Hour Helpers
  10. * @summary Rounds the given date to the nearest hour
  11. *
  12. * @description
  13. * Rounds the given date to the nearest hour (or number of hours).
  14. * Rounds up when the given date is exactly between the nearest round hours.
  15. *
  16. * @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).
  17. * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
  18. *
  19. * @param date - The date to round
  20. * @param options - An object with options.
  21. *
  22. * @returns The new date rounded to the closest hour
  23. *
  24. * @example
  25. * // Round 10 July 2014 12:34:56 to nearest hour:
  26. * const result = roundToNearestHours(new Date(2014, 6, 10, 12, 34, 56))
  27. * //=> Thu Jul 10 2014 13:00:00
  28. *
  29. * @example
  30. * // Round 10 July 2014 12:34:56 to nearest half hour:
  31. * const result = roundToNearestHours(new Date(2014, 6, 10, 12, 34, 56), { nearestTo: 6 })
  32. * //=> Thu Jul 10 2014 12:00:00
  33. *
  34. * @example
  35. * // Round 10 July 2014 12:34:56 to nearest half hour:
  36. * const result = roundToNearestHours(new Date(2014, 6, 10, 12, 34, 56), { nearestTo: 8 })
  37. * //=> Thu Jul 10 2014 16:00:00
  38. *
  39. * @example
  40. * // Floor (rounds down) 10 July 2014 12:34:56 to nearest hour:
  41. * const result = roundToNearestHours(new Date(2014, 6, 10, 1, 23, 45), { roundingMethod: 'ceil' })
  42. * //=> Thu Jul 10 2014 02:00:00
  43. *
  44. * @example
  45. * // Ceil (rounds up) 10 July 2014 12:34:56 to nearest quarter hour:
  46. * const result = roundToNearestHours(new Date(2014, 6, 10, 12, 34, 56), { roundingMethod: 'floor', nearestTo: 8 })
  47. * //=> Thu Jul 10 2014 08:00:00
  48. */
  49. export function roundToNearestHours(date, options) {
  50. const nearestTo = options?.nearestTo ?? 1;
  51. if (nearestTo < 1 || nearestTo > 12)
  52. return constructFrom(options?.in || date, NaN);
  53. const date_ = toDate(date, options?.in);
  54. const fractionalMinutes = date_.getMinutes() / 60;
  55. const fractionalSeconds = date_.getSeconds() / 60 / 60;
  56. const fractionalMilliseconds = date_.getMilliseconds() / 1000 / 60 / 60;
  57. const hours =
  58. date_.getHours() +
  59. fractionalMinutes +
  60. fractionalSeconds +
  61. fractionalMilliseconds;
  62. const method = options?.roundingMethod ?? "round";
  63. const roundingMethod = getRoundingMethod(method);
  64. const roundedHours = roundingMethod(hours / nearestTo) * nearestTo;
  65. date_.setHours(roundedHours, 0, 0, 0);
  66. return date_;
  67. }
  68. // Fallback for modularized imports:
  69. export default roundToNearestHours;