import { startOfWeek, startOfMonth, endOfWeek, endOfMonth, isBefore, addDays, isSameDay, isSameMonth, addMonths, isValid, min, max, } from 'date-fns'; import { DateRange } from './types'; export const identity = (x: T) => x; export const chunks = (array: ReadonlyArray, size: number): T[][] => ( Array.from( { length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size), ) ); export const isWithinRange = (date: Date, startDate: Date, endDate: Date) => { if (date && startDate && endDate) { return startDate.getTime() <= date.getTime() && date.getTime() <= endDate.getTime() } return false; } export const getDaysInMonth = (date: Date) => { const startWeek = startOfWeek(startOfMonth(date)); const endWeek = endOfWeek(endOfMonth(date)); const days = []; for (let curr = startWeek; isBefore(curr, endWeek);) { days.push(curr); curr = addDays(curr, 1); } return days; }; export const isStartOfRange = ({ startDate }: DateRange, day: Date) => ( (startDate && isSameDay(day, startDate)) as boolean ); export const isEndOfRange = ({ endDate }: DateRange, day: Date) => ( (endDate && isSameDay(day, endDate)) as boolean ); export const inDateRange = ({ startDate, endDate }: DateRange, day: Date) => ( startDate && endDate && (isWithinRange(day, startDate, endDate) || isSameDay(day, startDate) || isSameDay(day, endDate)) ) as boolean; export const isRangeSameDay = ({ startDate, endDate }: DateRange) => { if (startDate && endDate) { return isSameDay(startDate, endDate); } return false; }; type Falsy = false | null | undefined | 0 | ''; export const parseOptionalDate = (date: Date | string | Falsy, defaultValue: Date) => { if (date) { try { const parsed = new Date(date); if (isValid(parsed)) return parsed; } catch { } } return defaultValue; }; export const getValidatedMonths = (range: DateRange, minDate: Date, maxDate: Date) => { const { startDate, endDate } = range; if (startDate && endDate) { const newStart = max([startDate, minDate]); const newEnd = min([endDate, maxDate]); return [newStart, isSameMonth(newStart, newEnd) ? addMonths(newStart, 1) : newEnd]; } return [startDate, endDate]; };