UNPKG

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