chinese-days
Version:
中国节假日、调休日、工作日、24节气查询,农历阳历互转,支持 TS、CommonJS、UMD 模块化使用,提供 ics 日历格式,可供 Google Calendar、Apple Calendar、Microsoft Outlook 等客户端订阅。
223 lines (200 loc) • 6.67 kB
text/typescript
/* 自己实现一个简易的 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") {
this._date = new Date(date);
if (typeof date === "string" && isNaN(this._date.getTime())) {
this._date = new Date(date.replace(/-/g, "/"));
}
} 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;