import { dayjs, dayjsLocal } from '../../utils/dayjs' import type { Dayjs } from 'dayjs' import type { DatePickerDateObj as DateObj } from './types' // Constant list of month labels export const months: string[] = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ] // Start of given month (0-indexed month) export function monthStart(year: number, monthIndex: number): Dayjs { return dayjs(`${year}-${monthIndex + 1}-01`) } // Build weeks grid for the calendar export function generateWeeks( year: number, monthIndex: number, selected: string, ): DateObj[][] { const start = monthStart(year, monthIndex).startOf('week') const end = monthStart(year, monthIndex).endOf('month').endOf('week') const days: DateObj[] = [] let d: Dayjs = start while (d.isBefore(end) || d.isSame(end)) { const inMonth = d.month() === monthIndex const sel = dayjs(selected) days.push({ date: d, key: d.format('YYYY-MM-DD'), inMonth, isToday: d.isSame(dayjsLocal().format('YYYY-MM-DD'), 'day'), isSelected: sel.isValid() && d.isSame(sel, 'day'), }) d = d.add(1, 'day') } const chunked: DateObj[][] = [] for (let i = 0; i < days.length; i += 7) chunked.push(days.slice(i, i + 7)) return chunked } type DateConstructorParam = string | number | Date function getDate(...args: DateConstructorParam[]): Date { return new Date(...(args as [DateConstructorParam])) } function getDateValue(date: Date | string) { if (!date || date.toString() === 'Invalid Date') return '' return dayjs(date) .set('hour', 0) .set('minute', 0) .set('second', 0) .set('millisecond', 0) .format('YYYY-MM-DD') } function getDatesAfter(date: Date, count: number) { let incrementer = 1 if (count < 0) { incrementer = -1 count = Math.abs(count) } const dates: Date[] = [] while (count) { date = getDate( date.getFullYear(), date.getMonth(), date.getDate() + incrementer, ) dates.push(date) count-- } if (incrementer === -1) { return dates.reverse() } return dates } function getDaysInMonth(monthIndex: number, year: number) { const daysInMonthMap = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] const daysInMonth = daysInMonthMap[monthIndex] if (monthIndex === 1 && isLeapYear(year)) { return 29 } return daysInMonth } function isLeapYear(year: number) { if (year % 400 === 0) return true if (year % 100 === 0) return false if (year % 4 === 0) return true return false } export { getDate, getDateValue, getDatesAfter, getDaysInMonth, isLeapYear }