MCPcopy
hub / github.com/date-fns/date-fns / addMonths

Function addMonths

pkgs/core/src/addMonths/index.ts:38–84  ·  view source on GitHub ↗
(
  date: DateArg<DateType>,
  amount: number,
  options?: AddMonthsOptions<ResultDate> | undefined,
)

Source from the content-addressed store, hash-verified

36 * //=> Tue Feb 28 2023 00:00:00
37 */
38export function addMonths<
39 DateType extends Date,
40 ResultDate extends Date = DateType,
41>(
42 date: DateArg<DateType>,
43 amount: number,
44 options?: AddMonthsOptions<ResultDate> | undefined,
45): ResultDate {
46 const _date = toDate(date, options?.in);
47 if (isNaN(amount)) return constructFrom(options?.in || date, NaN);
48 if (!amount) {
49 // If 0 months, no-op to avoid changing times in the hour before end of DST
50 return _date;
51 }
52 const dayOfMonth = _date.getDate();
53
54 // The JS Date object supports date math by accepting out-of-bounds values for
55 // month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and
56 // new Date(2020, 13, 1) returns 1 Feb 2021. This is *almost* the behavior we
57 // want except that dates will wrap around the end of a month, meaning that
58 // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So
59 // we'll default to the end of the desired month by adding 1 to the desired
60 // month and using a date of 0 to back up one day to the end of the desired
61 // month.
62 const endOfDesiredMonth = constructFrom(options?.in || date, _date.getTime());
63 endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
64 const daysInMonth = endOfDesiredMonth.getDate();
65 if (dayOfMonth >= daysInMonth) {
66 // If we're already at the end of the month, then this is the correct date
67 // and we're done.
68 return endOfDesiredMonth;
69 } else {
70 // Otherwise, we now know that setting the original day-of-month value won't
71 // cause an overflow, so set the desired day-of-month. Note that we can't
72 // just set the date of `endOfDesiredMonth` because that object may have had
73 // its time changed in the unusual case where where a DST transition was on
74 // the last day of the month and its local time was in the hour skipped or
75 // repeated next to a DST transition. So we use `date` instead which is
76 // guaranteed to still have the original time.
77 _date.setFullYear(
78 endOfDesiredMonth.getFullYear(),
79 endOfDesiredMonth.getMonth(),
80 dayOfMonth,
81 );
82 return _date;
83 }
84}

Callers 6

addYearsFunction · 0.90
test.tsFile · 0.90
addQuartersFunction · 0.90
addFunction · 0.90
test.tsFile · 0.90
subMonthsFunction · 0.90

Calls 2

toDateFunction · 0.90
constructFromFunction · 0.90

Tested by

no test coverage detected