jm-mrc-components
Version:
移动端可复用组件库
296 lines (259 loc) • 7.12 kB
text/typescript
/**
* 将日期相关的帮助方法抽离到jslib
*/
import Lunar from 'chinese-lunar'
import getHoliday from './chinessHoliday'
export interface DateDesc {
time: Date
id: number
value: number
isPass?: boolean
isFuture?: boolean
isWeekDay?: boolean
lunar?: string
holiday?: string
}
export type DateDescList = DateDesc[]
interface GenDatesOptions {
lunar: boolean
holiday?: boolean
}
export const ChineseWeekDay = ['日', '一', '二', '三', '四', '五', '六']
export const Today = new Date()
export const ONE_WEEK = 7 * 24 * 3600 * 1000
const monthCache = {}
const defaultOptions = {
lunar: true,
holiday: true,
}
export function genDates(
date: Date,
option: GenDatesOptions = defaultOptions,
): DateDesc[] {
// 缓存
const cacheKey = `${date.getFullYear()}${date.getMonth()}`
if (cacheKey in monthCache) {
return monthCache[cacheKey]
}
let arr: DateDesc[] = []
let time = new Date(date) // copy
// 获取当月的第一天
time.setMonth(time.getMonth(), 1)
// 当月第一天的星期数
let curFirstDay = time.getDay()
/** 获取上个月的最后几天 **/
// 更新为上个月的最后一天
time.setDate(0)
let lastDayCount = time.getDate()
let tempYear = time.getFullYear()
let tempMonth = time.getMonth()
for (let i = curFirstDay; i > 0; i--) {
let date = lastDayCount - i + 1
let tempTime = new Date(tempYear, tempMonth, date)
tempTime = startOfDate(tempTime)
arr.push({
time: tempTime,
id: tempTime.getTime(),
value: date,
isPass: true,
isWeekDay: isWeekDay(tempTime),
lunar: option.lunar ? Lunar.solarToLunar(tempTime, 'D') : undefined,
holiday: option.holiday ? getHoliday(tempTime) : undefined,
})
}
/** 当月的日期数据 **/
// 移动到获取当月的最后一天
time.setMonth(time.getMonth() + 2, 0)
// 当月的天数
const curDayCount = time.getDate()
tempYear = time.getFullYear()
tempMonth = time.getMonth()
for (let i = 1; i <= curDayCount; i++) {
let tempTime = new Date(tempYear, tempMonth, i)
tempTime = startOfDate(tempTime)
arr.push({
time: tempTime,
id: tempTime.getTime(),
value: i,
isWeekDay: isWeekDay(tempTime),
lunar: option.lunar ? Lunar.solarToLunar(tempTime, 'D') : undefined,
holiday: option.holiday ? getHoliday(tempTime) : undefined,
})
}
/** 下个月的前几天 **/
let count = arr.length <= 35 ? 35 : 42
let j = 1
let l = count - arr.length + 1
time.setMonth(tempMonth + 1, 1)
tempYear = time.getFullYear()
tempMonth = time.getMonth()
while (j < l) {
let tempTime = new Date(tempYear, tempMonth, j)
tempTime = startOfDate(tempTime)
arr.push({
time: tempTime,
id: tempTime.getTime(),
value: j,
isFuture: true,
isWeekDay: isWeekDay(tempTime),
lunar: option.lunar ? Lunar.solarToLunar(tempTime, 'D') : undefined,
holiday: option.holiday ? getHoliday(tempTime) : undefined,
})
j++
}
// freeze object
return (monthCache[cacheKey] = arr)
}
export function isWeekDay(date: Date) {
const day = date.getDay()
return day != 0 && day != 6
}
export function isSameYear(a: Date, b: Date) {
return a.getFullYear() === b.getFullYear()
}
export function isSameMonth(a: Date, b: Date) {
return isSameYear(a, b) && a.getMonth() === b.getMonth()
}
export function isSameDay(a: Date, b: Date) {
return (
a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate()
)
}
export function isSameHour(a: Date, b: Date) {
return isSameDay(a, b) && a.getHours() === b.getHours()
}
export function isSameMinute(a: Date, b: Date) {
return isSameHour(a, b) && a.getMinutes() === b.getMinutes()
}
/**
* 判断是否是闰年
* @param year
*/
export function isLeap(year: number) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
}
export function isToday(date: Date) {
return isSameDay(Today, date)
}
export function inRange(start: Date, end: Date, value: Date) {
if (end.getTime() < start.getTime()) {
const temp = start
start = end
end = temp
}
return value >= start && value <= end
}
export function inRangeIgnoreTime(start: Date, end: Date, value: Date) {
if (end.getTime() < start.getTime()) {
const temp = start
start = end
end = temp
}
return (
isSameDay(start, value) ||
isSameDay(end, value) ||
inRange(start, end, value)
)
}
export function inMonth(month: Date, value: Date) {
const start = new Date(month)
start.setDate(1)
start.setHours(0, 0, 0, 0)
const end = new Date(start)
end.setMonth(end.getMonth() + 1)
end.setDate(0)
end.setHours(23, 59, 59, 999)
return inRange(start, end, value)
}
export function yesterday(date: Date) {
const copy = new Date(date)
copy.setDate(copy.getDate() - 1)
return copy
}
export function tomorrow(date: Date) {
const copy = new Date(date)
copy.setDate(copy.getDate() + 1)
return copy
}
export function startOfDate(date: Date) {
const copy = new Date(date)
copy.setHours(0, 0, 0, 0)
return copy
}
export function endOfDate(date: Date) {
const copy = new Date(date)
copy.setHours(23, 59, 59, 999)
return copy
}
export function midOfDate(date: Date) {
const copy = new Date(date)
copy.setHours(12, 0, 0, 0)
return copy
}
export function outOfCurrentYear(date: Date) {
return date.getFullYear() !== Today.getFullYear()
}
export function getLastDateOfMonth(date: Date) {
const copy = new Date(date)
copy.setMonth(copy.getMonth() + 1)
copy.setDate(0)
return copy.getDate()
}
export function afterHour(date: Date, hour: number = 1) {
const copy = new Date(date)
copy.setHours(copy.getHours() + hour)
return copy
}
export function afterDay(date: Date, day: number = 1) {
const copy = new Date(date)
copy.setDate(copy.getDate() + day)
return copy
}
export function afterMonth(date: Date, month: number = 1) {
const copy = new Date(date)
copy.setDate(1)
copy.setMonth(copy.getMonth() + month)
const lastDate = getLastDateOfMonth(copy)
if (date.getDate() > lastDate) {
copy.setDate(lastDate)
} else {
copy.setDate(date.getDate())
}
return copy
}
export function afterYear(date: Date, year: number = 1) {
return afterMonth(date, year * 12)
}
export function monthDiff(a: Date, b: Date) {
const yearDiff = a.getFullYear() - b.getFullYear()
const monthDiff = a.getMonth() - b.getMonth()
return yearDiff * 12 + monthDiff
}
export function copyDate(from: Date, to: Date) {
to.setFullYear(from.getFullYear())
to.setMonth(from.getMonth())
to.setDate(from.getDate())
return to
}
export function copyTime(from: Date, to: Date) {
to.setHours(
from.getHours(),
from.getMinutes(),
from.getSeconds(),
from.getMilliseconds(),
)
return to
}
export function roundHour(date: Date) {
const copy = new Date(date)
const min = copy.getMinutes()
copy.setMinutes(0)
copy.setSeconds(0)
copy.setMilliseconds(0)
if (min > 0) {
copy.setHours(copy.getHours() + 1)
}
return copy
}