All files occurrence-in-month.ts

100% Statements 26/26
100% Branches 12/12
100% Functions 1/1
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 411x 1x 1x 1x 1x                         1x 86x 86x 86x 86x 86x 86x 86x 86x 14x 14x 14x 86x 2x 2x   70x 70x 86x   62x 8x 86x  
import { addTime } from './add-time.ts';
import { beginningOfMonth } from './beginning-of-month.ts';
import { type DateOptions, type DayOfWeek, daysPerWeek } from './date.ts';
import { daysInMonth } from './days-in-month.ts';
import { modulo } from './modulo.ts';
 
/**
 * Determine the date of an occurrence of a weekday within a month
 * @param input - A date within the month in question
 * @param dayOfWeek - The day of the week to find the occurrence
 * @param occurrence - The occurrence number, or 'last' to find the last occurrence
 * @param options - see {@link DateOptions}
 * @defaultValue utc false
 * @returns A date object corresponding to the occurrence requested, or null if no such date exists in the month
 * @group Time
 * @category Day
 */
export function occurrenceInMonth(
  input: Date,
  dayOfWeek: DayOfWeek,
  occurrence: number | 'last',
  { utc = false }: DateOptions = {},
): Date | null {
  let day = beginningOfMonth(input, { utc });
  const jump = modulo(dayOfWeek - (utc ? day.getUTCDay() : day.getDay()), daysPerWeek);
  if (occurrence === 'last') {
    return addTime(day, {
      days: jump + Math.floor((daysInMonth(input, { utc }) - jump - 1) / daysPerWeek) * daysPerWeek,
    });
  } else if (occurrence < 1 || occurrence > 5) {
    return null;
  }
 
  day = addTime(day, { days: jump + daysPerWeek * (occurrence - 1) });
  return (
      utc ? day.getUTCMonth() === input.getUTCMonth() : day.getMonth() === input.getMonth()
    ) ?
      day
    : null;
}