0%

TypeScript扩展Date对象

今天做代码检查的时候发现,关于时间处理这一块可以做进一步提取。

最初的想法是,自定义一个类,继承Date,运行的时候抛出了一个很奇怪的错误:

1
Uncaught TypeError: this is not a Date object.

经过查找,发现有人也遇到了相同的问题: 如何继承Date对象?

最终采用原型扩展的方式实现,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
declare global {
interface Date {
fmt: (format: string) => string;
addDays: (days: number) => Date;
isToday: () => boolean;
clone: () => Date;
isAnotherMonth: (date: Date) => boolean;
isWeekend: () => boolean;
isSameDate: (date: Date) => boolean;
isLeapYear: () => boolean;
}
}

/* eslint no-extend-native: ["error", { "exceptions": ["Date"] }] */
Date.prototype.fmt = function (format = 'YYYY-MM-DD hh:mm:ss'): string {
const o: { [key: string]: number } = {
'Y+': this.getFullYear(), // year
'M+': this.getMonth() + 1, // month
'D+': this.getDate(), // day
'h+': this.getHours(), // hour
'm+': this.getMinutes(), // minute
's+': this.getSeconds(), // second
q: Math.floor((this.getMonth() + 3) / 3), // quarter
S: this.getMilliseconds() // millisecond
}

if (/(Y+)/.test(format)) {
format = format.replace(RegExp.$1, `${o['Y+']}`.substr(4 - RegExp.$1.length))
}

for (const k in o) {
if (new RegExp(`(${k})`).test(format)) {
const value = RegExp.$1.length > 1 && o[k] < 10 ? `0${o[k]}` : o[k]
format = format.replace(RegExp.$1, value as string)
}
}
return format
}

Date.prototype.addDays = function (days: number): Date {
if (days) {
this.setDate(this.getDate() + days)
}
return this
}

Date.prototype.isToday = function (): boolean {
return this.isSameDate(new Date())
}

Date.prototype.clone = function (): Date {
return new Date(+this)
}

Date.prototype.isAnotherMonth = function (date: Date): boolean {
return date && this.getMonth() !== date.getMonth()
}

Date.prototype.isWeekend = function (): boolean {
return this.getDay() === 0 || this.getDay() === 6
}

Date.prototype.isSameDate = function (date: Date): boolean {
return date && this.getFullYear() === date.getFullYear() && this.getMonth() === date.getMonth() && this.getDate() === date.getDate()
}

Date.prototype.isLeapYear = function (): boolean {
const year = this.getFullYear()
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
}

export {}