@daysnap/horn-ui
Version:
hron ui
79 lines (77 loc) • 3.04 kB
text/typescript
import { formatDate } from '@daysnap/utils'
import type { CalendarDay } from './types'
type calendarGenerator = (firstDayOfMonth: Date, maxDate?: Date, minDate?: Date) => CalendarDay[]
export const calendarGenerator: calendarGenerator = (firstDayOfMonth, maxDate, minDate) => {
if (minDate) {
minDate = new Date(formatDate(minDate, 'yyyy/MM/dd'))
}
if (maxDate) {
maxDate = new Date(formatDate(maxDate, 'yyyy/MM/dd'))
}
//一页要显示多少天,因为一个月最多31天,也就是最多一个月最多有六周,也就是现实6*7天,先把这个容器准备好
const date: CalendarDay[] = new Array(6 * 7)
//先算出来这月第一天是周几
const year = firstDayOfMonth.getFullYear()
const month = firstDayOfMonth.getMonth() + 1
const firstDayOfWeek = firstDayOfMonth.getDay() || 7 //获取当月第一天是星期几
const dayCountOfThisMonth = new Date(year, month, 0).getDate() //获取本月中天数
const prevIndexOfThisMonth = firstDayOfWeek - 1 //把周几转换成index
const NextIndexOfThisMonth = firstDayOfWeek + dayCountOfThisMonth - 2 //这个月的最后一天转换成index
const dayCountOfPrevMonth = new Date(year, month - 1, 0).getDate() //获取上一月中天数
const prevDateMonth = new Date(year, month - 1, 0) //创建一个上一个月的Date对象
const nextDateMonth = new Date(year, month + 1, 0) //创建一个上一个月的Date对象
// isGrey是用来判断他如果不是本月的日子就给个灰色
for (let i = 0; i < 6 * 7; i++) {
// 上月
if (i < prevIndexOfThisMonth) {
//firstDayOfWeek-1转换成index -1 转换成间隔几天 +i 算上当天是几号
const value = dayCountOfPrevMonth - (firstDayOfWeek - 1 - 1) + i
prevDateMonth.setDate(value)
const dateTime = formatDate(prevDateMonth, 'yyyy/MM/dd')
date[i] = {
value,
dateTime,
isOtherDays: true,
disable: false,
}
}
//本月
if (i >= prevIndexOfThisMonth && i <= NextIndexOfThisMonth) {
const value = i - (firstDayOfWeek - 1) + 1
firstDayOfMonth.setDate(value)
const dateTime = formatDate(firstDayOfMonth, 'yyyy/MM/dd')
date[i] = {
value,
dateTime,
isOtherDays: false,
disable: false,
}
}
// 下月
if (i > NextIndexOfThisMonth) {
const value = i - firstDayOfWeek - dayCountOfThisMonth + 2
nextDateMonth.setDate(value)
const dateTime = formatDate(nextDateMonth, 'yyyy/MM/dd')
date[i] = {
value,
dateTime,
isOtherDays: true,
disable: false,
}
}
}
date.forEach((i) => {
if (maxDate) {
i.disable = new Date(i.dateTime).getTime() > maxDate.getTime()
}
if (minDate) {
i.disable = new Date(i.dateTime).getTime() < minDate.getTime()
}
if (maxDate && minDate) {
i.disable =
new Date(i.dateTime).getTime() > maxDate.getTime() ||
new Date(i.dateTime).getTime() < minDate.getTime()
}
})
return date
}