发布于 

用ts实现一个时间转换器

封装一个时间转换器,可以将传入的时间(类似:2023-3-17)转成小时、周、月、年(和当前时间比较)

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//定义时间策略对象
const timeStrategies = {
'A': () => {
return '今天'
},
'B': (day:number|null) => {
return day + '天前'
},
'C': (week:number|null) => {
return week + '周前'
},
'D': () => {
return "半个月前"
},
'E': (month:number|null) => {
return month + "月前"
},
'F': () => {
return "半年前"
},
'G': (year:number|null) => {
return year + "年前"
}
}

//时间转换器类
class DateTransfer {
nowTimeStamp:number
hours:number
constructor() {

this.nowTimeStamp = new Date().getTime();
this.hours = 0
}
//将类似2023-01-15格式转化为时间戳
transferToTimeStamp(userTime:string) {
if (userTime) {
let userTimeStamp = new Date(userTime).getTime()
return this.getTimeDiff(userTimeStamp)
}
}
//获取时间差
getTimeDiff(userTimeStamp:number):number|undefined {
if (userTimeStamp && userTimeStamp < this.nowTimeStamp) {
return (this.nowTimeStamp - userTimeStamp) / 1000
}
}
//将用户传入的时间转为小时
toHours(userTime:string):number|undefined {
if (userTime) {
let timeDiff = this.transferToTimeStamp(userTime);
this.hours = Math.trunc(timeDiff as number / 3600);
return this.hours
}

}
//转为天数
toDays(userTime:string) {
if (userTime) {
this.hours = this.toHours(userTime) as number
let days = this.hours / 24
return Math.trunc(days)
}

}
//转为周数
toWeeks(userTime:string|number) {
//如果是字符,就是用户传入的时间
//如果是数字,那么就是天数
if (typeof userTime === 'string') {
//先将小时数转为天数再计算
let days = this.toDays(userTime) as number
let weeks = days / 7
return Math.trunc(weeks)
}
let weeks = userTime / 7
return Math.trunc(weeks)

}
//转为月数
toMonths(userTime:string|number) {
//假设一个月30天
//先将小时数转为天数再计算
//如果是字符,就是用户传入的时间
//如果是数字,那么就是天数
if (typeof userTime == 'string') {
let days = this.toDays(userTime) as number
let months = days / 30
//截取小数后两位返回
return this.getNum(months, 0)
}
let months = userTime / 30
//截取小数后两位返回
return this.getNum(months, 0)
}
//转为年数
toYears(userTime:string|number) {
//假设一年365天
//先将小时数转为天数再计算
//如果是字符,就是用户传入的时间
//如果是数字,那么就是天数
if (typeof userTime == 'string') {
let days = this.toDays(userTime) as number
let years = days / 365
return this.getNum(years, 0)
}
let years = userTime/365
return this.getNum(years, 0)

}
//截取小数后两位
getNum(num:number, cut = 3) {
//将数字转为string
let numStr = num.toString()

let indexEnd = numStr.indexOf(".") + cut
let result = numStr
if (indexEnd != -1) {
result = numStr.slice(0, indexEnd)
}
//slice方法会改变原数组

//将string转为数字返回
return Number(result)
}
//自动换算时间单位(最小单位为天)
//计算:如time=1.2就为1天前
//time<=1为今天,time<7为x天前
//7<=time<15为x周前,15<=time<30为半个月前
//30<=time<180为x月前,180<=time<365为半年前
//365<=time为x年前
autoTransfer(userTime:string) {
if (userTime) {
//获取天数
let days = this.toDays(userTime) as number;
// console.log(days)
let index = 'A';
let value = null;
//判断时间
if (days <= 1) {
//当天
index = 'A'
} else if (days > 1 && days < 7) {
//x天前
// debugger
// console.log(days)
index = 'B'
value = days
} else if (days >= 7 && days < 15) {
//x周前
index = 'C'
value = this.toWeeks(days)
} else if (days >= 15 && days < 30) {
//半个月前
index = 'D'

} else if (days >= 30 && days < 180) {
//x月前
index = 'E'
value = this.toMonths(days)
} else if (days >= 180 && days < 365) {
//半年前
index = 'F'
}
else if (days >= 365) {
//x年前
index = 'G'
value = this.toYears(days)
}
return timeStrategies[index as keyof typeof timeStrategies](value)
//如果只是timeSet[index](value),编译器会报错
//因为传入index字段,在编译器看来是一个字符串,
//而不是A、B、C这几个值的一种,因此类型是不一致的
//想要正确使用,就需要显示声明传入的值与这些键一致
}


}
}

//实例化一个转换器
const obj = new DateTransfer()
//自动转换时间
console.log(obj.autoTransfer('2023-01-17'))
//控制台输出:2月前