UNPKG

chinese-days

Version:

中国节假日、调休日、工作日、24节气查询,农历阳历互转,支持 TS、CommonJS、UMD 模块化使用,提供 ics 日历格式,可供 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端订阅。

241 lines (218 loc) 7.12 kB
/* 自己实现一个简易的 dayjs,供项目中使用 */ export type ConfigType = string | number | Date | Dayjs | null | undefined; export class Dayjs { private _date: Date; private static daysOfWeek = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; constructor(date?: ConfigType) { if (date instanceof Dayjs) { this._date = new Date(date.toDate()); } else if (date instanceof Date) { this._date = new Date(date); } else if (typeof date === 'string' || typeof date === 'number') { if (typeof date === 'string') { // Regex to match YYYY-MM-DD or YYYY-M-D const match = date.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/); if (match) { // Parse as UTC explicitly to ensure consistency and avoid Local/UTC mixing // This handles '2004-10-9' (Local in V8) vs '2004-10-10' (UTC in V8) inconsistency this._date = new Date(Date.UTC( parseInt(match[1], 10), parseInt(match[2], 10) - 1, parseInt(match[3], 10) )); } else if (isNaN(new Date(date).getTime())) { // Fallback for slash format or other formats this._date = new Date(date.replace(/-/g, '/')); } else { this._date = new Date(date); } } else { this._date = new Date(date); } } else { this._date = new Date(); } } toDate(): Date { return this._date; } isValid(): boolean { return !isNaN(this._date.getTime()); } diff( date: string | number | Date | Dayjs | null | undefined, unit: 'day' | 'month' | 'year' = 'day' ): number { const targetDate = new Dayjs(date).toDate(); const diffTime = this._date.getTime() - targetDate.getTime(); switch (unit) { case 'year': return this._date.getFullYear() - targetDate.getFullYear(); case 'month': return ( (this._date.getFullYear() - targetDate.getFullYear()) * 12 + (this._date.getMonth() - targetDate.getMonth()) ); case 'day': default: return Math.floor(diffTime / (1000 * 60 * 60 * 24)); } } startOf(unit?: 'year' | 'month' | 'day'): Dayjs { const newDate = new Date(this._date); switch (unit) { case 'year': newDate.setMonth(0); newDate.setDate(1); newDate.setHours(0, 0, 0, 0); break; case 'month': newDate.setDate(1); newDate.setHours(0, 0, 0, 0); break; case 'day': newDate.setHours(0, 0, 0, 0); break; } return new Dayjs(newDate); } endOf(unit?: 'year' | 'month' | 'day'): Dayjs { const newDate = new Date(this._date); switch (unit) { case 'year': newDate.setMonth(11); newDate.setDate(31); newDate.setHours(23, 59, 59, 999); break; case 'month': newDate.setDate( new Date(newDate.getFullYear(), newDate.getMonth() + 1, 0).getDate() ); newDate.setHours(23, 59, 59, 999); break; case 'day': newDate.setHours(23, 59, 59, 999); break; } return new Dayjs(newDate); } add(value: number, unit: 'year' | 'month' | 'day'): Dayjs { const newDate = new Date(this._date); switch (unit) { case 'year': newDate.setFullYear(newDate.getFullYear() + value); break; case 'month': newDate.setMonth(newDate.getMonth() + value); break; case 'day': newDate.setDate(newDate.getDate() + value); break; } return new Dayjs(newDate); } subtract(value: number, unit: 'year' | 'month' | 'day'): Dayjs { return this.add(-value, unit); } format(formatStr: string): string { const map: { [key: string]: number | string } = { YYYY: this._date.getFullYear(), MM: (this._date.getMonth() + 1).toString().padStart(2, '0'), DD: this._date.getDate().toString().padStart(2, '0'), HH: this._date.getHours().toString().padStart(2, '0'), mm: this._date.getMinutes().toString().padStart(2, '0'), ss: this._date.getSeconds().toString().padStart(2, '0'), dddd: Dayjs.daysOfWeek[this._date.getDay()], }; return formatStr.replace(/YYYY|MM|DD|HH|mm|ss|dddd/g, matched => { return map[matched].toString(); }); } year(): number; year(year: number): Dayjs; year(year?: number): number | Dayjs { if (year === undefined) return this._date.getFullYear(); const newDate = new Date(this._date); newDate.setFullYear(year); return new Dayjs(newDate); } month(): number; month(month: number): Dayjs; month(month?: number): number | Dayjs { if (month === undefined) return this._date.getMonth(); const newDate = new Date(this._date); newDate.setMonth(month); return new Dayjs(newDate); } date(): number; date(day: number): Dayjs; date(day?: number): number | Dayjs { if (day === undefined) return this._date.getDate(); const newDate = new Date(this._date); newDate.setDate(day); return new Dayjs(newDate); } day(): number; day(day: number): Dayjs; day(day?: number): number | Dayjs { if (day === undefined) { return this._date.getDay(); } else { const currentDay = this._date.getDay(); const diff = day - currentDay; const newDate = new Date(this._date); newDate.setDate(this._date.getDate() + diff); return new Dayjs(newDate); } } isBefore(date: string | number | Date | Dayjs | null | undefined): boolean { const targetDate = new Dayjs(date).toDate(); return this._date.getTime() < targetDate.getTime(); } isAfter(date: string | number | Date | Dayjs | null | undefined): boolean { const targetDate = new Dayjs(date).toDate(); return this._date.getTime() > targetDate.getTime(); } isSame( date: string | number | Date | Dayjs | null | undefined, unit: 'year' | 'month' | 'day' = 'day' ): boolean { const targetDate = new Dayjs(date).toDate(); switch (unit) { case 'year': return this._date.getFullYear() === targetDate.getFullYear(); case 'month': return ( this._date.getFullYear() === targetDate.getFullYear() && this._date.getMonth() === targetDate.getMonth() ); case 'day': default: return ( this._date.getFullYear() === targetDate.getFullYear() && this._date.getMonth() === targetDate.getMonth() && this._date.getDate() === targetDate.getDate() ); } } isBetween( startDate: string | number | Date | Dayjs | null | undefined, endDate: string | number | Date | Dayjs | null | undefined, unit?: 'year' | 'month' | 'day' ): boolean { const start = new Dayjs(startDate).startOf(unit).toDate(); const end = new Dayjs(endDate).endOf(unit).toDate(); const current = this.toDate(); return current >= start && current <= end; } } const simpleDayjs = (date?: ConfigType): Dayjs => new Dayjs(date); export default simpleDayjs;