sanity-plugin-recurring-dates 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -7,6 +7,7 @@ import * as React from 'react';
7
7
  import React__default, { useState, useEffect, PureComponent, useCallback, forwardRef, useRef, useMemo } from 'react';
8
8
  import { rrulestr, Weekday, RRule } from 'rrule';
9
9
  import { Feedback } from 'sanity-plugin-utils';
10
+ import { toDate as toDate$1, format as format$1 } from 'date-fns-tz';
10
11
  import { format, parse, DEFAULT_DATE_FORMAT as DEFAULT_DATE_FORMAT$1, DEFAULT_TIME_FORMAT } from '@sanity/util/legacyDateFormat';
11
12
  const DEFAULT_RECURRENCES = ["RRULE:FREQ=DAILY;INTERVAL=1", "RRULE:FREQ=WEEKLY;INTERVAL=1", "RRULE:FREQ=MONTHLY;INTERVAL=1", "RRULE:FREQ=YEARLY;INTERVAL=1"];
12
13
  const DEFAULT_CONFIG = {
@@ -2707,20 +2708,84 @@ process.env.NODE_ENV !== "production" ? {
2707
2708
  children: PropTypes.node.isRequired,
2708
2709
  className: PropTypes.string
2709
2710
  } : {};
2710
- function toInteger(dirtyNumber) {
2711
- if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
2712
- return NaN;
2713
- }
2714
- var number = Number(dirtyNumber);
2715
- if (isNaN(number)) {
2716
- return number;
2717
- }
2718
- return number < 0 ? Math.ceil(number) : Math.floor(number);
2719
- }
2720
- function requiredArgs(required, args) {
2721
- if (args.length < required) {
2722
- throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');
2723
- }
2711
+
2712
+ /**
2713
+ * @module constants
2714
+ * @summary Useful constants
2715
+ * @description
2716
+ * Collection of useful date constants.
2717
+ *
2718
+ * The constants could be imported from `date-fns/constants`:
2719
+ *
2720
+ * ```ts
2721
+ * import { maxTime, minTime } from "./constants/date-fns/constants";
2722
+ *
2723
+ * function isAllowedTime(time) {
2724
+ * return time <= maxTime && time >= minTime;
2725
+ * }
2726
+ * ```
2727
+ */
2728
+
2729
+ /**
2730
+ * @constant
2731
+ * @name millisecondsInWeek
2732
+ * @summary Milliseconds in 1 week.
2733
+ */
2734
+ const millisecondsInWeek = 604800000;
2735
+
2736
+ /**
2737
+ * @constant
2738
+ * @name constructFromSymbol
2739
+ * @summary Symbol enabling Date extensions to inherit properties from the reference date.
2740
+ *
2741
+ * The symbol is used to enable the `constructFrom` function to construct a date
2742
+ * using a reference date and a value. It allows to transfer extra properties
2743
+ * from the reference date to the new date. It's useful for extensions like
2744
+ * [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as
2745
+ * a constructor argument.
2746
+ */
2747
+ const constructFromSymbol = Symbol.for("constructDateFrom");
2748
+
2749
+ /**
2750
+ * @name constructFrom
2751
+ * @category Generic Helpers
2752
+ * @summary Constructs a date using the reference date and the value
2753
+ *
2754
+ * @description
2755
+ * The function constructs a new date using the constructor from the reference
2756
+ * date and the given value. It helps to build generic functions that accept
2757
+ * date extensions.
2758
+ *
2759
+ * It defaults to `Date` if the passed reference date is a number or a string.
2760
+ *
2761
+ * Starting from v3.7.0, it allows to construct a date using `[Symbol.for("constructDateFrom")]`
2762
+ * enabling to transfer extra properties from the reference date to the new date.
2763
+ * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
2764
+ * that accept a time zone as a constructor argument.
2765
+ *
2766
+ * @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).
2767
+ *
2768
+ * @param date - The reference date to take constructor from
2769
+ * @param value - The value to create the date
2770
+ *
2771
+ * @returns Date initialized using the given date and value
2772
+ *
2773
+ * @example
2774
+ * import { constructFrom } from "./constructFrom/date-fns";
2775
+ *
2776
+ * // A function that clones a date preserving the original type
2777
+ * function cloneDate<DateType extends Date>(date: DateType): DateType {
2778
+ * return constructFrom(
2779
+ * date, // Use constructor from the given date
2780
+ * date.getTime() // Use the date value to create a new date
2781
+ * );
2782
+ * }
2783
+ */
2784
+ function constructFrom(date, value) {
2785
+ if (typeof date === "function") return date(value);
2786
+ if (date && typeof date === "object" && constructFromSymbol in date) return date[constructFromSymbol](value);
2787
+ if (date instanceof Date) return new date.constructor(value);
2788
+ return new Date(value);
2724
2789
  }
2725
2790
 
2726
2791
  /**
@@ -2737,11 +2802,19 @@ function requiredArgs(required, args) {
2737
2802
  *
2738
2803
  * If the argument is none of the above, the function returns Invalid Date.
2739
2804
  *
2805
+ * Starting from v3.7.0, it clones a date using `[Symbol.for("constructDateFrom")]`
2806
+ * enabling to transfer extra properties from the reference date to the new date.
2807
+ * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
2808
+ * that accept a time zone as a constructor argument.
2809
+ *
2740
2810
  * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
2741
2811
  *
2742
- * @param {Date|Number} argument - the value to convert
2743
- * @returns {Date} the parsed date in the local time zone
2744
- * @throws {TypeError} 1 argument required
2812
+ * @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).
2813
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2814
+ *
2815
+ * @param argument - The value to convert
2816
+ *
2817
+ * @returns The parsed date in the local time zone
2745
2818
  *
2746
2819
  * @example
2747
2820
  * // Clone the date:
@@ -2753,27 +2826,15 @@ function requiredArgs(required, args) {
2753
2826
  * const result = toDate(1392098430000)
2754
2827
  * //=> Tue Feb 11 2014 11:30:30
2755
2828
  */
2756
- function toDate(argument) {
2757
- requiredArgs(1, arguments);
2758
- var argStr = Object.prototype.toString.call(argument);
2759
-
2760
- // Clone the date
2761
- if (argument instanceof Date || _typeof(argument) === 'object' && argStr === '[object Date]') {
2762
- // Prevent the date to lose the milliseconds when passed to new Date() in IE10
2763
- return new Date(argument.getTime());
2764
- } else if (typeof argument === 'number' || argStr === '[object Number]') {
2765
- return new Date(argument);
2766
- } else {
2767
- if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {
2768
- // eslint-disable-next-line no-console
2769
- console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments");
2770
- // eslint-disable-next-line no-console
2771
- console.warn(new Error().stack);
2772
- }
2773
- return new Date(NaN);
2774
- }
2829
+ function toDate(argument, context) {
2830
+ // [TODO] Get rid of `toDate` or `constructFrom`?
2831
+ return constructFrom(argument, argument);
2775
2832
  }
2776
2833
 
2834
+ /**
2835
+ * The {@link addDays} function options.
2836
+ */
2837
+
2777
2838
  /**
2778
2839
  * @name addDays
2779
2840
  * @category Day Helpers
@@ -2782,31 +2843,34 @@ function toDate(argument) {
2782
2843
  * @description
2783
2844
  * Add the specified number of days to the given date.
2784
2845
  *
2785
- * @param {Date|Number} date - the date to be changed
2786
- * @param {Number} amount - the amount of days to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
2787
- * @returns {Date} - the new date with the days added
2788
- * @throws {TypeError} - 2 arguments required
2846
+ * @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).
2847
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2848
+ *
2849
+ * @param date - The date to be changed
2850
+ * @param amount - The amount of days to be added.
2851
+ * @param options - An object with options
2852
+ *
2853
+ * @returns The new date with the days added
2789
2854
  *
2790
2855
  * @example
2791
2856
  * // Add 10 days to 1 September 2014:
2792
2857
  * const result = addDays(new Date(2014, 8, 1), 10)
2793
2858
  * //=> Thu Sep 11 2014 00:00:00
2794
2859
  */
2795
- function addDays(dirtyDate, dirtyAmount) {
2796
- requiredArgs(2, arguments);
2797
- var date = toDate(dirtyDate);
2798
- var amount = toInteger(dirtyAmount);
2799
- if (isNaN(amount)) {
2800
- return new Date(NaN);
2801
- }
2802
- if (!amount) {
2803
- // If 0 days, no-op to avoid changing times in the hour before end of DST
2804
- return date;
2805
- }
2806
- date.setDate(date.getDate() + amount);
2807
- return date;
2860
+ function addDays(date, amount, options) {
2861
+ const _date = toDate(date);
2862
+ if (isNaN(amount)) return constructFrom(date, NaN);
2863
+
2864
+ // If 0 days, no-op to avoid changing times in the hour before end of DST
2865
+ if (!amount) return _date;
2866
+ _date.setDate(_date.getDate() + amount);
2867
+ return _date;
2808
2868
  }
2809
2869
 
2870
+ /**
2871
+ * The {@link addMonths} function options.
2872
+ */
2873
+
2810
2874
  /**
2811
2875
  * @name addMonths
2812
2876
  * @category Month Helpers
@@ -2815,28 +2879,32 @@ function addDays(dirtyDate, dirtyAmount) {
2815
2879
  * @description
2816
2880
  * Add the specified number of months to the given date.
2817
2881
  *
2818
- * @param {Date|Number} date - the date to be changed
2819
- * @param {Number} amount - the amount of months to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
2820
- * @returns {Date} the new date with the months added
2821
- * @throws {TypeError} 2 arguments required
2882
+ * @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).
2883
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2884
+ *
2885
+ * @param date - The date to be changed
2886
+ * @param amount - The amount of months to be added.
2887
+ * @param options - The options object
2888
+ *
2889
+ * @returns The new date with the months added
2822
2890
  *
2823
2891
  * @example
2824
2892
  * // Add 5 months to 1 September 2014:
2825
2893
  * const result = addMonths(new Date(2014, 8, 1), 5)
2826
2894
  * //=> Sun Feb 01 2015 00:00:00
2895
+ *
2896
+ * // Add one month to 30 January 2023:
2897
+ * const result = addMonths(new Date(2023, 0, 30), 1)
2898
+ * //=> Tue Feb 28 2023 00:00:00
2827
2899
  */
2828
- function addMonths(dirtyDate, dirtyAmount) {
2829
- requiredArgs(2, arguments);
2830
- var date = toDate(dirtyDate);
2831
- var amount = toInteger(dirtyAmount);
2832
- if (isNaN(amount)) {
2833
- return new Date(NaN);
2834
- }
2900
+ function addMonths(date, amount, options) {
2901
+ const _date = toDate(date);
2902
+ if (isNaN(amount)) return constructFrom(date, NaN);
2835
2903
  if (!amount) {
2836
2904
  // If 0 months, no-op to avoid changing times in the hour before end of DST
2837
- return date;
2905
+ return _date;
2838
2906
  }
2839
- var dayOfMonth = date.getDate();
2907
+ const dayOfMonth = _date.getDate();
2840
2908
 
2841
2909
  // The JS Date object supports date math by accepting out-of-bounds values for
2842
2910
  // month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and
@@ -2846,9 +2914,9 @@ function addMonths(dirtyDate, dirtyAmount) {
2846
2914
  // we'll default to the end of the desired month by adding 1 to the desired
2847
2915
  // month and using a date of 0 to back up one day to the end of the desired
2848
2916
  // month.
2849
- var endOfDesiredMonth = new Date(date.getTime());
2850
- endOfDesiredMonth.setMonth(date.getMonth() + amount + 1, 0);
2851
- var daysInMonth = endOfDesiredMonth.getDate();
2917
+ const endOfDesiredMonth = constructFrom(date, _date.getTime());
2918
+ endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
2919
+ const daysInMonth = endOfDesiredMonth.getDate();
2852
2920
  if (dayOfMonth >= daysInMonth) {
2853
2921
  // If we're already at the end of the month, then this is the correct date
2854
2922
  // and we're done.
@@ -2861,15 +2929,19 @@ function addMonths(dirtyDate, dirtyAmount) {
2861
2929
  // the last day of the month and its local time was in the hour skipped or
2862
2930
  // repeated next to a DST transition. So we use `date` instead which is
2863
2931
  // guaranteed to still have the original time.
2864
- date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
2865
- return date;
2932
+ _date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
2933
+ return _date;
2866
2934
  }
2867
2935
  }
2868
- var defaultOptions = {};
2936
+ let defaultOptions = {};
2869
2937
  function getDefaultOptions() {
2870
2938
  return defaultOptions;
2871
2939
  }
2872
2940
 
2941
+ /**
2942
+ * The {@link startOfWeek} function options.
2943
+ */
2944
+
2873
2945
  /**
2874
2946
  * @name startOfWeek
2875
2947
  * @category Week Helpers
@@ -2879,13 +2951,13 @@ function getDefaultOptions() {
2879
2951
  * Return the start of a week for the given date.
2880
2952
  * The result will be in the local timezone.
2881
2953
  *
2882
- * @param {Date|Number} date - the original date
2883
- * @param {Object} [options] - an object with options.
2884
- * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
2885
- * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
2886
- * @returns {Date} the start of a week
2887
- * @throws {TypeError} 1 argument required
2888
- * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
2954
+ * @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).
2955
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2956
+ *
2957
+ * @param date - The original date
2958
+ * @param options - An object with options
2959
+ *
2960
+ * @returns The start of a week
2889
2961
  *
2890
2962
  * @example
2891
2963
  * // The start of a week for 2 September 2014 11:55:00:
@@ -2897,24 +2969,28 @@ function getDefaultOptions() {
2897
2969
  * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
2898
2970
  * //=> Mon Sep 01 2014 00:00:00
2899
2971
  */
2900
- function startOfWeek(dirtyDate, options) {
2901
- var _ref, _ref2, _ref3, _options$weekStartsOn, _defaultOptions$local, _defaultOptions$local2;
2902
- requiredArgs(1, arguments);
2903
- var defaultOptions = getDefaultOptions();
2904
- var weekStartsOn = toInteger((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = void 0) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : void 0) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0);
2905
-
2906
- // Test if weekStartsOn is between 0 and 6 _and_ is not NaN
2907
- if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) {
2908
- throw new RangeError('weekStartsOn must be between 0 and 6 inclusively');
2972
+ function startOfWeek(date, options) {
2973
+ const defaultOptions = getDefaultOptions();
2974
+ const weekStartsOn = defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
2975
+ const _date = toDate(date);
2976
+ const day = _date.getDay();
2977
+ const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
2978
+ _date.setDate(_date.getDate() - diff);
2979
+ _date.setHours(0, 0, 0, 0);
2980
+ return _date;
2981
+ }
2982
+ function normalizeDates(context) {
2983
+ for (var _len = arguments.length, dates = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2984
+ dates[_key - 1] = arguments[_key];
2909
2985
  }
2910
- var date = toDate(dirtyDate);
2911
- var day = date.getDay();
2912
- var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
2913
- date.setDate(date.getDate() - diff);
2914
- date.setHours(0, 0, 0, 0);
2915
- return date;
2986
+ const normalize = constructFrom.bind(null, dates.find(date => typeof date === "object"));
2987
+ return dates.map(normalize);
2916
2988
  }
2917
2989
 
2990
+ /**
2991
+ * The {@link startOfDay} function options.
2992
+ */
2993
+
2918
2994
  /**
2919
2995
  * @name startOfDay
2920
2996
  * @category Day Helpers
@@ -2924,47 +3000,59 @@ function startOfWeek(dirtyDate, options) {
2924
3000
  * Return the start of a day for the given date.
2925
3001
  * The result will be in the local timezone.
2926
3002
  *
2927
- * @param {Date|Number} date - the original date
2928
- * @returns {Date} the start of a day
2929
- * @throws {TypeError} 1 argument required
3003
+ * @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).
3004
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3005
+ *
3006
+ * @param date - The original date
3007
+ * @param options - The options
3008
+ *
3009
+ * @returns The start of a day
2930
3010
  *
2931
3011
  * @example
2932
3012
  * // The start of a day for 2 September 2014 11:55:00:
2933
3013
  * const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
2934
3014
  * //=> Tue Sep 02 2014 00:00:00
2935
3015
  */
2936
- function startOfDay(dirtyDate) {
2937
- requiredArgs(1, arguments);
2938
- var date = toDate(dirtyDate);
2939
- date.setHours(0, 0, 0, 0);
2940
- return date;
3016
+ function startOfDay(date, options) {
3017
+ const _date = toDate(date);
3018
+ _date.setHours(0, 0, 0, 0);
3019
+ return _date;
2941
3020
  }
2942
3021
 
3022
+ /**
3023
+ * The {@link addWeeks} function options.
3024
+ */
3025
+
2943
3026
  /**
2944
3027
  * @name addWeeks
2945
3028
  * @category Week Helpers
2946
3029
  * @summary Add the specified number of weeks to the given date.
2947
3030
  *
2948
3031
  * @description
2949
- * Add the specified number of week to the given date.
3032
+ * Add the specified number of weeks to the given date.
3033
+ *
3034
+ * @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).
3035
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2950
3036
  *
2951
- * @param {Date|Number} date - the date to be changed
2952
- * @param {Number} amount - the amount of weeks to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.
2953
- * @returns {Date} the new date with the weeks added
2954
- * @throws {TypeError} 2 arguments required
3037
+ * @param date - The date to be changed
3038
+ * @param amount - The amount of weeks to be added.
3039
+ * @param options - An object with options
3040
+ *
3041
+ * @returns The new date with the weeks added
2955
3042
  *
2956
3043
  * @example
2957
3044
  * // Add 4 weeks to 1 September 2014:
2958
3045
  * const result = addWeeks(new Date(2014, 8, 1), 4)
2959
3046
  * //=> Mon Sep 29 2014 00:00:00
2960
3047
  */
2961
- function addWeeks(dirtyDate, dirtyAmount) {
2962
- requiredArgs(2, arguments);
2963
- var amount = toInteger(dirtyAmount);
2964
- var days = amount * 7;
2965
- return addDays(dirtyDate, days);
3048
+ function addWeeks(date, amount, options) {
3049
+ return addDays(date, amount * 7);
2966
3050
  }
2967
3051
 
3052
+ /**
3053
+ * The {@link isSameDay} function options.
3054
+ */
3055
+
2968
3056
  /**
2969
3057
  * @name isSameDay
2970
3058
  * @category Day Helpers
@@ -2973,10 +3061,11 @@ function addWeeks(dirtyDate, dirtyAmount) {
2973
3061
  * @description
2974
3062
  * Are the given dates in the same day (and year and month)?
2975
3063
  *
2976
- * @param {Date|Number} dateLeft - the first date to check
2977
- * @param {Date|Number} dateRight - the second date to check
2978
- * @returns {Boolean} the dates are in the same day (and year and month)
2979
- * @throws {TypeError} 2 arguments required
3064
+ * @param laterDate - The first date to check
3065
+ * @param earlierDate - The second date to check
3066
+ * @param options - An object with options
3067
+ *
3068
+ * @returns The dates are in the same day (and year and month)
2980
3069
  *
2981
3070
  * @example
2982
3071
  * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?
@@ -2993,13 +3082,28 @@ function addWeeks(dirtyDate, dirtyAmount) {
2993
3082
  * const result = isSameDay(new Date(2014, 8, 4), new Date(2015, 8, 4))
2994
3083
  * //=> false
2995
3084
  */
2996
- function isSameDay(dirtyDateLeft, dirtyDateRight) {
2997
- requiredArgs(2, arguments);
2998
- var dateLeftStartOfDay = startOfDay(dirtyDateLeft);
2999
- var dateRightStartOfDay = startOfDay(dirtyDateRight);
3000
- return dateLeftStartOfDay.getTime() === dateRightStartOfDay.getTime();
3085
+ function isSameDay(laterDate, earlierDate, options) {
3086
+ const [dateLeft_, dateRight_] = normalizeDates(options?.in, laterDate, earlierDate);
3087
+ return +startOfDay(dateLeft_) === +startOfDay(dateRight_);
3088
+ }
3089
+ function normalizeInterval(context, interval) {
3090
+ const [start, end] = normalizeDates(context, interval.start, interval.end);
3091
+ return {
3092
+ start,
3093
+ end
3094
+ };
3001
3095
  }
3002
3096
 
3097
+ /**
3098
+ * The {@link eachWeekOfInterval} function options.
3099
+ */
3100
+
3101
+ /**
3102
+ * The {@link eachWeekOfInterval} function result type. It resolves the proper data type.
3103
+ * It uses the first argument date object type, starting from the interval start date,
3104
+ * then the end interval date. If a context function is passed, it uses the context function return type.
3105
+ */
3106
+
3003
3107
  /**
3004
3108
  * @name eachWeekOfInterval
3005
3109
  * @category Interval Helpers
@@ -3008,15 +3112,10 @@ function isSameDay(dirtyDateLeft, dirtyDateRight) {
3008
3112
  * @description
3009
3113
  * Return the array of weeks within the specified time interval.
3010
3114
  *
3011
- * @param {Interval} interval - the interval. See [Interval]{@link https://date-fns.org/docs/Interval}
3012
- * @param {Object} [options] - an object with options.
3013
- * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
3014
- * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
3015
- * @returns {Date[]} the array with starts of weeks from the week of the interval start to the week of the interval end
3016
- * @throws {TypeError} 1 argument required
3017
- * @throws {RangeError} `options.weekStartsOn` must be 0, 1, ..., 6
3018
- * @throws {RangeError} The start of an interval cannot be after its end
3019
- * @throws {RangeError} Date in interval cannot be `Invalid Date`
3115
+ * @param interval - The interval.
3116
+ * @param options - An object with options.
3117
+ *
3118
+ * @returns The array with starts of weeks from the week of the interval start to the week of the interval end
3020
3119
  *
3021
3120
  * @example
3022
3121
  * // Each week within interval 6 October 2014 - 23 November 2014:
@@ -3035,88 +3134,66 @@ function isSameDay(dirtyDateLeft, dirtyDateRight) {
3035
3134
  * // Sun Nov 23 2014 00:00:00
3036
3135
  * // ]
3037
3136
  */
3038
- function eachWeekOfInterval(dirtyInterval, options) {
3039
- requiredArgs(1, arguments);
3040
- var interval = dirtyInterval || {};
3041
- var startDate = toDate(interval.start);
3042
- var endDate = toDate(interval.end);
3043
- var endTime = endDate.getTime();
3044
-
3045
- // Throw an exception if start date is after end date or if any date is `Invalid Date`
3046
- if (!(startDate.getTime() <= endTime)) {
3047
- throw new RangeError('Invalid interval');
3048
- }
3049
- var startDateWeek = startOfWeek(startDate, options);
3050
- var endDateWeek = startOfWeek(endDate, options);
3051
-
3052
- // Some timezones switch DST at midnight, making start of day unreliable in these timezones, 3pm is a safe bet
3137
+ function eachWeekOfInterval(interval, options) {
3138
+ const {
3139
+ start,
3140
+ end
3141
+ } = normalizeInterval(options?.in, interval);
3142
+ let reversed = +start > +end;
3143
+ const startDateWeek = reversed ? startOfWeek(end) : startOfWeek(start);
3144
+ const endDateWeek = reversed ? startOfWeek(start) : startOfWeek(end);
3053
3145
  startDateWeek.setHours(15);
3054
3146
  endDateWeek.setHours(15);
3055
- endTime = endDateWeek.getTime();
3056
- var weeks = [];
3057
- var currentWeek = startDateWeek;
3058
- while (currentWeek.getTime() <= endTime) {
3059
- currentWeek.setHours(0);
3060
- weeks.push(toDate(currentWeek));
3061
- currentWeek = addWeeks(currentWeek, 1);
3062
- currentWeek.setHours(15);
3147
+ const endTime = +endDateWeek.getTime();
3148
+ let currentDate = startDateWeek;
3149
+ let step = 1;
3150
+ const dates = [];
3151
+ while (+currentDate <= endTime) {
3152
+ currentDate.setHours(0);
3153
+ dates.push(constructFrom(start, currentDate));
3154
+ currentDate = addWeeks(currentDate, step);
3155
+ currentDate.setHours(15);
3063
3156
  }
3064
- return weeks;
3157
+ return reversed ? dates.reverse() : dates;
3065
3158
  }
3066
3159
 
3160
+ /**
3161
+ * The {@link startOfMonth} function options.
3162
+ */
3163
+
3067
3164
  /**
3068
3165
  * @name startOfMonth
3069
3166
  * @category Month Helpers
3070
3167
  * @summary Return the start of a month for the given date.
3071
3168
  *
3072
3169
  * @description
3073
- * Return the start of a month for the given date.
3074
- * The result will be in the local timezone.
3170
+ * Return the start of a month for the given date. The result will be in the local timezone.
3075
3171
  *
3076
- * @param {Date|Number} date - the original date
3077
- * @returns {Date} the start of a month
3078
- * @throws {TypeError} 1 argument required
3172
+ * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments.
3173
+ * Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3174
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed,
3175
+ * or inferred from the arguments.
3176
+ *
3177
+ * @param date - The original date
3178
+ * @param options - An object with options
3179
+ *
3180
+ * @returns The start of a month
3079
3181
  *
3080
3182
  * @example
3081
3183
  * // The start of a month for 2 September 2014 11:55:00:
3082
3184
  * const result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))
3083
3185
  * //=> Mon Sep 01 2014 00:00:00
3084
3186
  */
3085
- function startOfMonth(dirtyDate) {
3086
- requiredArgs(1, arguments);
3087
- var date = toDate(dirtyDate);
3088
- date.setDate(1);
3089
- date.setHours(0, 0, 0, 0);
3090
- return date;
3187
+ function startOfMonth(date, options) {
3188
+ const _date = toDate(date);
3189
+ _date.setDate(1);
3190
+ _date.setHours(0, 0, 0, 0);
3191
+ return _date;
3091
3192
  }
3092
3193
 
3093
3194
  /**
3094
- * @name getDaysInMonth
3095
- * @category Month Helpers
3096
- * @summary Get the number of days in a month of the given date.
3097
- *
3098
- * @description
3099
- * Get the number of days in a month of the given date.
3100
- *
3101
- * @param {Date|Number} date - the given date
3102
- * @returns {Number} the number of days in a month
3103
- * @throws {TypeError} 1 argument required
3104
- *
3105
- * @example
3106
- * // How many days are in February 2000?
3107
- * const result = getDaysInMonth(new Date(2000, 1))
3108
- * //=> 29
3195
+ * The {@link getWeekYear} function options.
3109
3196
  */
3110
- function getDaysInMonth(dirtyDate) {
3111
- requiredArgs(1, arguments);
3112
- var date = toDate(dirtyDate);
3113
- var year = date.getFullYear();
3114
- var monthIndex = date.getMonth();
3115
- var lastDayOfMonth = new Date(0);
3116
- lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);
3117
- lastDayOfMonth.setHours(0, 0, 0, 0);
3118
- return lastDayOfMonth.getDate();
3119
- }
3120
3197
 
3121
3198
  /**
3122
3199
  * @name getWeekYear
@@ -3130,17 +3207,12 @@ function getDaysInMonth(dirtyDate) {
3130
3207
  * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3131
3208
  * the first week of the week-numbering year)
3132
3209
  *
3133
- * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering
3210
+ * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3211
+ *
3212
+ * @param date - The given date
3213
+ * @param options - An object with options.
3134
3214
  *
3135
- * @param {Date|Number} date - the given date
3136
- * @param {Object} [options] - an object with options.
3137
- * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
3138
- * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
3139
- * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year
3140
- * @returns {Number} the local week-numbering year
3141
- * @throws {TypeError} 1 argument required
3142
- * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
3143
- * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
3215
+ * @returns The local week-numbering year
3144
3216
  *
3145
3217
  * @example
3146
3218
  * // Which week numbering year is 26 December 2004 with the default settings?
@@ -3157,35 +3229,32 @@ function getDaysInMonth(dirtyDate) {
3157
3229
  * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })
3158
3230
  * //=> 2004
3159
3231
  */
3160
- function getWeekYear(dirtyDate, options) {
3161
- var _ref, _ref2, _ref3, _options$firstWeekCon, _defaultOptions$local, _defaultOptions$local2;
3162
- requiredArgs(1, arguments);
3163
- var date = toDate(dirtyDate);
3164
- var year = date.getFullYear();
3165
- var defaultOptions = getDefaultOptions();
3166
- var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = void 0) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : void 0) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1);
3167
-
3168
- // Test if weekStartsOn is between 1 and 7 _and_ is not NaN
3169
- if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) {
3170
- throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively');
3171
- }
3172
- var firstWeekOfNextYear = new Date(0);
3232
+ function getWeekYear(date, options) {
3233
+ const _date = toDate(date);
3234
+ const year = _date.getFullYear();
3235
+ const defaultOptions = getDefaultOptions();
3236
+ const firstWeekContainsDate = defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
3237
+ const firstWeekOfNextYear = constructFrom(date, 0);
3173
3238
  firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);
3174
3239
  firstWeekOfNextYear.setHours(0, 0, 0, 0);
3175
- var startOfNextYear = startOfWeek(firstWeekOfNextYear, options);
3176
- var firstWeekOfThisYear = new Date(0);
3240
+ const startOfNextYear = startOfWeek(firstWeekOfNextYear);
3241
+ const firstWeekOfThisYear = constructFrom(date, 0);
3177
3242
  firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);
3178
3243
  firstWeekOfThisYear.setHours(0, 0, 0, 0);
3179
- var startOfThisYear = startOfWeek(firstWeekOfThisYear, options);
3180
- if (date.getTime() >= startOfNextYear.getTime()) {
3244
+ const startOfThisYear = startOfWeek(firstWeekOfThisYear);
3245
+ if (+_date >= +startOfNextYear) {
3181
3246
  return year + 1;
3182
- } else if (date.getTime() >= startOfThisYear.getTime()) {
3247
+ } else if (+_date >= +startOfThisYear) {
3183
3248
  return year;
3184
3249
  } else {
3185
3250
  return year - 1;
3186
3251
  }
3187
3252
  }
3188
3253
 
3254
+ /**
3255
+ * The {@link startOfWeekYear} function options.
3256
+ */
3257
+
3189
3258
  /**
3190
3259
  * @name startOfWeekYear
3191
3260
  * @category Week-Numbering Year Helpers
@@ -3198,17 +3267,15 @@ function getWeekYear(dirtyDate, options) {
3198
3267
  * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3199
3268
  * the first week of the week-numbering year)
3200
3269
  *
3201
- * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering
3270
+ * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3271
+ *
3272
+ * @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).
3273
+ * @typeParam ResultDate - The result `Date` type.
3202
3274
  *
3203
- * @param {Date|Number} date - the original date
3204
- * @param {Object} [options] - an object with options.
3205
- * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
3206
- * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
3207
- * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year
3208
- * @returns {Date} the start of a week-numbering year
3209
- * @throws {TypeError} 1 argument required
3210
- * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
3211
- * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
3275
+ * @param date - The original date
3276
+ * @param options - An object with options
3277
+ *
3278
+ * @returns The start of a week-numbering year
3212
3279
  *
3213
3280
  * @example
3214
3281
  * // The start of an a week-numbering year for 2 July 2005 with default settings:
@@ -3225,19 +3292,20 @@ function getWeekYear(dirtyDate, options) {
3225
3292
  * })
3226
3293
  * //=> Mon Jan 03 2005 00:00:00
3227
3294
  */
3228
- function startOfWeekYear(dirtyDate, options) {
3229
- var _ref, _ref2, _ref3, _options$firstWeekCon, _defaultOptions$local, _defaultOptions$local2;
3230
- requiredArgs(1, arguments);
3231
- var defaultOptions = getDefaultOptions();
3232
- var firstWeekContainsDate = toInteger((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = void 0) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : void 0) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1);
3233
- var year = getWeekYear(dirtyDate, options);
3234
- var firstWeek = new Date(0);
3295
+ function startOfWeekYear(date, options) {
3296
+ const defaultOptions = getDefaultOptions();
3297
+ const firstWeekContainsDate = defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
3298
+ const year = getWeekYear(date);
3299
+ const firstWeek = constructFrom(date, 0);
3235
3300
  firstWeek.setFullYear(year, 0, firstWeekContainsDate);
3236
3301
  firstWeek.setHours(0, 0, 0, 0);
3237
- var date = startOfWeek(firstWeek, options);
3238
- return date;
3302
+ const _date = startOfWeek(firstWeek);
3303
+ return _date;
3239
3304
  }
3240
- var MILLISECONDS_IN_WEEK = 604800000;
3305
+
3306
+ /**
3307
+ * The {@link getWeek} function options.
3308
+ */
3241
3309
 
3242
3310
  /**
3243
3311
  * @name getWeek
@@ -3251,23 +3319,19 @@ var MILLISECONDS_IN_WEEK = 604800000;
3251
3319
  * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3252
3320
  * the first week of the week-numbering year)
3253
3321
  *
3254
- * Week numbering: https://en.wikipedia.org/wiki/Week#Week_numbering
3322
+ * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3323
+ *
3324
+ * @param date - The given date
3325
+ * @param options - An object with options
3255
3326
  *
3256
- * @param {Date|Number} date - the given date
3257
- * @param {Object} [options] - an object with options.
3258
- * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale}
3259
- * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday)
3260
- * @param {1|2|3|4|5|6|7} [options.firstWeekContainsDate=1] - the day of January, which is always in the first week of the year
3261
- * @returns {Number} the week
3262
- * @throws {TypeError} 1 argument required
3263
- * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6
3264
- * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7
3327
+ * @returns The week
3265
3328
  *
3266
3329
  * @example
3267
3330
  * // Which week of the local week numbering year is 2 January 2005 with default options?
3268
3331
  * const result = getWeek(new Date(2005, 0, 2))
3269
3332
  * //=> 2
3270
3333
  *
3334
+ * @example
3271
3335
  * // Which week of the local week numbering year is 2 January 2005,
3272
3336
  * // if Monday is the first day of the week,
3273
3337
  * // and the first week of the year always contains 4 January?
@@ -3277,18 +3341,52 @@ var MILLISECONDS_IN_WEEK = 604800000;
3277
3341
  * })
3278
3342
  * //=> 53
3279
3343
  */
3344
+ function getWeek(date, options) {
3345
+ const _date = toDate(date);
3346
+ const diff = +startOfWeek(_date) - +startOfWeekYear(_date);
3280
3347
 
3281
- function getWeek(dirtyDate, options) {
3282
- requiredArgs(1, arguments);
3283
- var date = toDate(dirtyDate);
3284
- var diff = startOfWeek(date, options).getTime() - startOfWeekYear(date, options).getTime();
3348
+ // Round the number of weeks to the nearest integer because the number of
3349
+ // milliseconds in a week is not constant (e.g. it's different in the week of
3350
+ // the daylight saving time clock shift).
3351
+ return Math.round(diff / millisecondsInWeek) + 1;
3352
+ }
3285
3353
 
3286
- // Round the number of days to the nearest integer
3287
- // because the number of milliseconds in a week is not constant
3288
- // (e.g. it's different in the week of the daylight saving time clock shift)
3289
- return Math.round(diff / MILLISECONDS_IN_WEEK) + 1;
3354
+ /**
3355
+ * The {@link getDaysInMonth} function options.
3356
+ */
3357
+
3358
+ /**
3359
+ * @name getDaysInMonth
3360
+ * @category Month Helpers
3361
+ * @summary Get the number of days in a month of the given date.
3362
+ *
3363
+ * @description
3364
+ * Get the number of days in a month of the given date, considering the context if provided.
3365
+ *
3366
+ * @param date - The given date
3367
+ * @param options - An object with options
3368
+ *
3369
+ * @returns The number of days in a month
3370
+ *
3371
+ * @example
3372
+ * // How many days are in February 2000?
3373
+ * const result = getDaysInMonth(new Date(2000, 1))
3374
+ * //=> 29
3375
+ */
3376
+ function getDaysInMonth(date, options) {
3377
+ const _date = toDate(date);
3378
+ const year = _date.getFullYear();
3379
+ const monthIndex = _date.getMonth();
3380
+ const lastDayOfMonth = constructFrom(_date, 0);
3381
+ lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);
3382
+ lastDayOfMonth.setHours(0, 0, 0, 0);
3383
+ return lastDayOfMonth.getDate();
3290
3384
  }
3291
3385
 
3386
+ /**
3387
+ * The {@link lastDayOfMonth} function options.
3388
+ */
3389
+
3292
3390
  /**
3293
3391
  * @name lastDayOfMonth
3294
3392
  * @category Month Helpers
@@ -3298,24 +3396,31 @@ function getWeek(dirtyDate, options) {
3298
3396
  * Return the last day of a month for the given date.
3299
3397
  * The result will be in the local timezone.
3300
3398
  *
3301
- * @param {Date|Number} date - the original date
3302
- * @returns {Date} the last day of a month
3303
- * @throws {TypeError} 1 argument required
3399
+ * @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).
3400
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3401
+ *
3402
+ * @param date - The original date
3403
+ * @param options - An object with options
3404
+ *
3405
+ * @returns The last day of a month
3304
3406
  *
3305
3407
  * @example
3306
3408
  * // The last day of a month for 2 September 2014 11:55:00:
3307
3409
  * const result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))
3308
3410
  * //=> Tue Sep 30 2014 00:00:00
3309
3411
  */
3310
- function lastDayOfMonth(dirtyDate) {
3311
- requiredArgs(1, arguments);
3312
- var date = toDate(dirtyDate);
3313
- var month = date.getMonth();
3314
- date.setFullYear(date.getFullYear(), month + 1, 0);
3315
- date.setHours(0, 0, 0, 0);
3316
- return date;
3412
+ function lastDayOfMonth(date, options) {
3413
+ const _date = toDate(date);
3414
+ const month = _date.getMonth();
3415
+ _date.setFullYear(_date.getFullYear(), month + 1, 0);
3416
+ _date.setHours(0, 0, 0, 0);
3417
+ return toDate(_date);
3317
3418
  }
3318
3419
 
3420
+ /**
3421
+ * The {@link isSameMonth} function options.
3422
+ */
3423
+
3319
3424
  /**
3320
3425
  * @name isSameMonth
3321
3426
  * @category Month Helpers
@@ -3324,10 +3429,11 @@ function lastDayOfMonth(dirtyDate) {
3324
3429
  * @description
3325
3430
  * Are the given dates in the same month (and year)?
3326
3431
  *
3327
- * @param {Date|Number} dateLeft - the first date to check
3328
- * @param {Date|Number} dateRight - the second date to check
3329
- * @returns {Boolean} the dates are in the same month (and year)
3330
- * @throws {TypeError} 2 arguments required
3432
+ * @param laterDate - The first date to check
3433
+ * @param earlierDate - The second date to check
3434
+ * @param options - An object with options
3435
+ *
3436
+ * @returns The dates are in the same month (and year)
3331
3437
  *
3332
3438
  * @example
3333
3439
  * // Are 2 September 2014 and 25 September 2014 in the same month?
@@ -3339,13 +3445,15 @@ function lastDayOfMonth(dirtyDate) {
3339
3445
  * const result = isSameMonth(new Date(2014, 8, 2), new Date(2015, 8, 25))
3340
3446
  * //=> false
3341
3447
  */
3342
- function isSameMonth(dirtyDateLeft, dirtyDateRight) {
3343
- requiredArgs(2, arguments);
3344
- var dateLeft = toDate(dirtyDateLeft);
3345
- var dateRight = toDate(dirtyDateRight);
3346
- return dateLeft.getFullYear() === dateRight.getFullYear() && dateLeft.getMonth() === dateRight.getMonth();
3448
+ function isSameMonth(laterDate, earlierDate, options) {
3449
+ const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
3450
+ return laterDate_.getFullYear() === earlierDate_.getFullYear() && laterDate_.getMonth() === earlierDate_.getMonth();
3347
3451
  }
3348
3452
 
3453
+ /**
3454
+ * The {@link setMonth} function options.
3455
+ */
3456
+
3349
3457
  /**
3350
3458
  * @name setMonth
3351
3459
  * @category Month Helpers
@@ -3354,32 +3462,38 @@ function isSameMonth(dirtyDateLeft, dirtyDateRight) {
3354
3462
  * @description
3355
3463
  * Set the month to the given date.
3356
3464
  *
3357
- * @param {Date|Number} date - the date to be changed
3358
- * @param {Number} month - the month of the new date
3359
- * @returns {Date} the new date with the month set
3360
- * @throws {TypeError} 2 arguments required
3465
+ * @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).
3466
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3467
+ *
3468
+ * @param date - The date to be changed
3469
+ * @param month - The month index to set (0-11)
3470
+ * @param options - The options
3471
+ *
3472
+ * @returns The new date with the month set
3361
3473
  *
3362
3474
  * @example
3363
3475
  * // Set February to 1 September 2014:
3364
3476
  * const result = setMonth(new Date(2014, 8, 1), 1)
3365
3477
  * //=> Sat Feb 01 2014 00:00:00
3366
3478
  */
3367
- function setMonth(dirtyDate, dirtyMonth) {
3368
- requiredArgs(2, arguments);
3369
- var date = toDate(dirtyDate);
3370
- var month = toInteger(dirtyMonth);
3371
- var year = date.getFullYear();
3372
- var day = date.getDate();
3373
- var dateWithDesiredMonth = new Date(0);
3374
- dateWithDesiredMonth.setFullYear(year, month, 15);
3375
- dateWithDesiredMonth.setHours(0, 0, 0, 0);
3376
- var daysInMonth = getDaysInMonth(dateWithDesiredMonth);
3377
- // Set the last day of the new month
3378
- // if the original date was the last day of the longer month
3379
- date.setMonth(month, Math.min(day, daysInMonth));
3380
- return date;
3479
+ function setMonth(date, month, options) {
3480
+ const _date = toDate(date);
3481
+ const year = _date.getFullYear();
3482
+ const day = _date.getDate();
3483
+ const midMonth = constructFrom(date, 0);
3484
+ midMonth.setFullYear(year, month, 15);
3485
+ midMonth.setHours(0, 0, 0, 0);
3486
+ const daysInMonth = getDaysInMonth(midMonth);
3487
+
3488
+ // Set the earlier date, allows to wrap Jan 31 to Feb 28
3489
+ _date.setMonth(month, Math.min(day, daysInMonth));
3490
+ return _date;
3381
3491
  }
3382
3492
 
3493
+ /**
3494
+ * The {@link setDate} function options.
3495
+ */
3496
+
3383
3497
  /**
3384
3498
  * @name setDate
3385
3499
  * @category Day Helpers
@@ -3388,24 +3502,30 @@ function setMonth(dirtyDate, dirtyMonth) {
3388
3502
  * @description
3389
3503
  * Set the day of the month to the given date.
3390
3504
  *
3391
- * @param {Date|Number} date - the date to be changed
3392
- * @param {Number} dayOfMonth - the day of the month of the new date
3393
- * @returns {Date} the new date with the day of the month set
3394
- * @throws {TypeError} 2 arguments required
3505
+ * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows using extensions like [`UTCDate`](https://github.com/date-fns/utc).
3506
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3507
+ *
3508
+ * @param date - The date to be changed
3509
+ * @param dayOfMonth - The day of the month of the new date
3510
+ * @param options - The options
3511
+ *
3512
+ * @returns The new date with the day of the month set
3395
3513
  *
3396
3514
  * @example
3397
3515
  * // Set the 30th day of the month to 1 September 2014:
3398
3516
  * const result = setDate(new Date(2014, 8, 1), 30)
3399
3517
  * //=> Tue Sep 30 2014 00:00:00
3400
3518
  */
3401
- function setDate(dirtyDate, dirtyDayOfMonth) {
3402
- requiredArgs(2, arguments);
3403
- var date = toDate(dirtyDate);
3404
- var dayOfMonth = toInteger(dirtyDayOfMonth);
3405
- date.setDate(dayOfMonth);
3406
- return date;
3519
+ function setDate(date, dayOfMonth, options) {
3520
+ const _date = toDate(date);
3521
+ _date.setDate(dayOfMonth);
3522
+ return _date;
3407
3523
  }
3408
3524
 
3525
+ /**
3526
+ * The {@link setHours} function options.
3527
+ */
3528
+
3409
3529
  /**
3410
3530
  * @name setHours
3411
3531
  * @category Hour Helpers
@@ -3414,24 +3534,30 @@ function setDate(dirtyDate, dirtyDayOfMonth) {
3414
3534
  * @description
3415
3535
  * Set the hours to the given date.
3416
3536
  *
3417
- * @param {Date|Number} date - the date to be changed
3418
- * @param {Number} hours - the hours of the new date
3419
- * @returns {Date} the new date with the hours set
3420
- * @throws {TypeError} 2 arguments required
3537
+ * @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).
3538
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3539
+ *
3540
+ * @param date - The date to be changed
3541
+ * @param hours - The hours of the new date
3542
+ * @param options - An object with options
3543
+ *
3544
+ * @returns The new date with the hours set
3421
3545
  *
3422
3546
  * @example
3423
3547
  * // Set 4 hours to 1 September 2014 11:30:00:
3424
3548
  * const result = setHours(new Date(2014, 8, 1, 11, 30), 4)
3425
3549
  * //=> Mon Sep 01 2014 04:30:00
3426
3550
  */
3427
- function setHours(dirtyDate, dirtyHours) {
3428
- requiredArgs(2, arguments);
3429
- var date = toDate(dirtyDate);
3430
- var hours = toInteger(dirtyHours);
3431
- date.setHours(hours);
3432
- return date;
3551
+ function setHours(date, hours, options) {
3552
+ const _date = toDate(date);
3553
+ _date.setHours(hours);
3554
+ return _date;
3433
3555
  }
3434
3556
 
3557
+ /**
3558
+ * The {@link setMinutes} function options.
3559
+ */
3560
+
3435
3561
  /**
3436
3562
  * @name setMinutes
3437
3563
  * @category Minute Helpers
@@ -3440,24 +3566,30 @@ function setHours(dirtyDate, dirtyHours) {
3440
3566
  * @description
3441
3567
  * Set the minutes to the given date.
3442
3568
  *
3443
- * @param {Date|Number} date - the date to be changed
3444
- * @param {Number} minutes - the minutes of the new date
3445
- * @returns {Date} the new date with the minutes set
3446
- * @throws {TypeError} 2 arguments required
3569
+ * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows using extensions like [`UTCDate`](https://github.com/date-fns/utc).
3570
+ * @typeParam ResultDate - The result `Date` type, returned from the context function, or inferred from the arguments.
3571
+ *
3572
+ * @param date - The date to be changed
3573
+ * @param minutes - The minutes of the new date
3574
+ * @param options - An object with options
3575
+ *
3576
+ * @returns The new date with the minutes set
3447
3577
  *
3448
3578
  * @example
3449
3579
  * // Set 45 minutes to 1 September 2014 11:30:40:
3450
3580
  * const result = setMinutes(new Date(2014, 8, 1, 11, 30, 40), 45)
3451
3581
  * //=> Mon Sep 01 2014 11:45:40
3452
3582
  */
3453
- function setMinutes(dirtyDate, dirtyMinutes) {
3454
- requiredArgs(2, arguments);
3455
- var date = toDate(dirtyDate);
3456
- var minutes = toInteger(dirtyMinutes);
3457
- date.setMinutes(minutes);
3458
- return date;
3583
+ function setMinutes(date, minutes, options) {
3584
+ const date_ = toDate(date);
3585
+ date_.setMinutes(minutes);
3586
+ return date_;
3459
3587
  }
3460
3588
 
3589
+ /**
3590
+ * The {@link setYear} function options.
3591
+ */
3592
+
3461
3593
  /**
3462
3594
  * @name setYear
3463
3595
  * @category Year Helpers
@@ -3466,27 +3598,27 @@ function setMinutes(dirtyDate, dirtyMinutes) {
3466
3598
  * @description
3467
3599
  * Set the year to the given date.
3468
3600
  *
3469
- * @param {Date|Number} date - the date to be changed
3470
- * @param {Number} year - the year of the new date
3471
- * @returns {Date} the new date with the year set
3472
- * @throws {TypeError} 2 arguments required
3601
+ * @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).
3602
+ * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3603
+ *
3604
+ * @param date - The date to be changed
3605
+ * @param year - The year of the new date
3606
+ * @param options - An object with options.
3607
+ *
3608
+ * @returns The new date with the year set
3473
3609
  *
3474
3610
  * @example
3475
3611
  * // Set year 2013 to 1 September 2014:
3476
3612
  * const result = setYear(new Date(2014, 8, 1), 2013)
3477
3613
  * //=> Sun Sep 01 2013 00:00:00
3478
3614
  */
3479
- function setYear(dirtyDate, dirtyYear) {
3480
- requiredArgs(2, arguments);
3481
- var date = toDate(dirtyDate);
3482
- var year = toInteger(dirtyYear);
3615
+ function setYear(date, year, options) {
3616
+ const date_ = toDate(date);
3483
3617
 
3484
3618
  // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date
3485
- if (isNaN(date.getTime())) {
3486
- return new Date(NaN);
3487
- }
3488
- date.setFullYear(year);
3489
- return date;
3619
+ if (isNaN(+date_)) return constructFrom(date, NaN);
3620
+ date_.setFullYear(year);
3621
+ return date_;
3490
3622
  }
3491
3623
  function CalendarDay(props) {
3492
3624
  const {
@@ -4069,14 +4201,14 @@ function DateInput(props) {
4069
4201
  onChange,
4070
4202
  type,
4071
4203
  value,
4072
- disabled,
4204
+ readOnly,
4073
4205
  ...rest
4074
4206
  } = props;
4075
4207
  const {
4076
4208
  dateFormat
4077
4209
  } = parseOptions(type.options);
4078
4210
  const handleChange = useCallback(nextDate => {
4079
- onChange(nextDate);
4211
+ onChange(nextDate || null);
4080
4212
  }, [onChange]);
4081
4213
  const formatInputValue = useCallback(date => format(date, dateFormat), [dateFormat]);
4082
4214
  const parseInputValue = useCallback(inputValue => parse(inputValue, dateFormat), [dateFormat]);
@@ -4087,7 +4219,7 @@ function DateInput(props) {
4087
4219
  formatInputValue,
4088
4220
  onChange: handleChange,
4089
4221
  parseInputValue,
4090
- readOnly: disabled,
4222
+ readOnly,
4091
4223
  selectTime: false,
4092
4224
  serialize,
4093
4225
  value
@@ -4231,7 +4363,7 @@ function CustomRule(_ref8) {
4231
4363
  return initialValue ? rrulestr(initialValue) : new RRule();
4232
4364
  }, [initialValue]);
4233
4365
  const [frequency, setFrequency] = useState(initialRule.origOptions.freq || 1);
4234
- const [interval, setInterval] = useState(initialRule.origOptions.interval || 1);
4366
+ const [interval, setInterval] = useState(initialRule.origOptions.interval && initialRule.origOptions.interval > 0 ? initialRule.origOptions.interval : 1);
4235
4367
  const [count, setCount] = useState(initialRule.origOptions.count || null);
4236
4368
  const [until, setUntil] = useState(initialRule.origOptions.until || null);
4237
4369
  const [byweekday, setByweekday] = useState(initialRule.origOptions.byweekday || null);
@@ -4243,7 +4375,7 @@ function CustomRule(_ref8) {
4243
4375
  if (name === "freq") {
4244
4376
  setFrequency(Number(value));
4245
4377
  } else if (name === "interval") {
4246
- setInterval(Number(value));
4378
+ setInterval(Number(value) > 1 ? Number(value) : 1);
4247
4379
  } else if (name === "count") {
4248
4380
  setCount(Number(value));
4249
4381
  }
@@ -4259,11 +4391,12 @@ function CustomRule(_ref8) {
4259
4391
  } else if (frequency === RRule.DAILY) {
4260
4392
  fromDate.setDate(fromDate.getDate() + DEFAULT_COUNTS[frequency]);
4261
4393
  }
4394
+ fromDate.setHours(23, 59, 59, 999);
4262
4395
  return fromDate;
4263
4396
  }, [frequency, startDate]);
4264
4397
  const handleUntilChange = useCallback(date => {
4265
4398
  if (date) {
4266
- setUntil(new Date(date));
4399
+ setUntil(toDate$1(`${date}T23:59:59`));
4267
4400
  }
4268
4401
  }, []);
4269
4402
  const handleEndChange = useCallback(event => {
@@ -4294,6 +4427,7 @@ function CustomRule(_ref8) {
4294
4427
  onClose();
4295
4428
  onChange(set(newRule.toString(), ["rrule"]));
4296
4429
  }, [byweekday, count, frequency, interval, onChange, onClose, until]);
4430
+ const formatUntilValue = useCallback(date => format$1(date, "yyyy-MM-dd"), []);
4297
4431
  return open ? /* @__PURE__ */jsx(Dialog, {
4298
4432
  header: "Custom recurrence",
4299
4433
  id: "dialog-example",
@@ -4323,6 +4457,7 @@ function CustomRule(_ref8) {
4323
4457
  children: /* @__PURE__ */jsx(TextInput, {
4324
4458
  name: "interval",
4325
4459
  type: "number",
4460
+ min: 1,
4326
4461
  value: interval,
4327
4462
  onChange: handleChange
4328
4463
  })
@@ -4333,16 +4468,16 @@ function CustomRule(_ref8) {
4333
4468
  onChange: handleChange,
4334
4469
  children: [/* @__PURE__ */jsx("option", {
4335
4470
  value: RRule.YEARLY,
4336
- children: "years"
4471
+ children: "year(s)"
4337
4472
  }), /* @__PURE__ */jsx("option", {
4338
4473
  value: RRule.MONTHLY,
4339
- children: "months"
4474
+ children: "month(s)"
4340
4475
  }), /* @__PURE__ */jsx("option", {
4341
4476
  value: RRule.WEEKLY,
4342
- children: "weeks"
4477
+ children: "week(s)"
4343
4478
  }), /* @__PURE__ */jsx("option", {
4344
4479
  value: RRule.DAILY,
4345
- children: "days"
4480
+ children: "day(s)"
4346
4481
  })]
4347
4482
  })
4348
4483
  })]
@@ -4399,8 +4534,8 @@ function CustomRule(_ref8) {
4399
4534
  title: "Date",
4400
4535
  options: dateTimeOptions
4401
4536
  },
4402
- value: until ? new Date(until) : getUntilDate(),
4403
- disabled: !until
4537
+ value: until ? formatUntilValue(new Date(until)) : formatUntilValue(getUntilDate()),
4538
+ readOnly: !until
4404
4539
  })
4405
4540
  })]
4406
4541
  }), /* @__PURE__ */jsxs(Flex, {
@@ -4434,7 +4569,7 @@ function CustomRule(_ref8) {
4434
4569
  style: {
4435
4570
  whiteSpace: "nowrap"
4436
4571
  },
4437
- children: "occurrences"
4572
+ children: "occurrence(s)"
4438
4573
  })]
4439
4574
  })]
4440
4575
  })]