JS获取时间,封装函数将时间减一天、一月、一年,并加以格式化,前端显示不同状态时间封装
写一个时间的utils文件,可以给公司或者个人使用的小工具。
一、获取时间的某个参数封装
1. 代码
在js中,为什么要封装一个这样看起来没什么作用的函数呢,主要是为了服务与其他函数调用,假如说写一个和包含时间的js库,那么这个东西,就会减少代码量,复用这个代码。
// 获取当前时间的 ms s min h day month year
function getSeverTime(time = new Date()) {
const Time = new Date(time)
return {
ms: Time.getMilliseconds(),
s: Time.getSeconds(),
min: Time.getMinutes(),
h: Time.getHours(),
date: Time.getDate(),
day: Time.getDay(),
month: Time.getMonth(),
year: Time.getFullYear(),
}
}
二、封装时间减一天,或者不同时间后的时间。
其实说js有对每一个时间有一个set的方法,去修改对应的时间,而我们封装一个方法可以重复重复一个函数去算一个复杂的时间,而对这个代码稍做处理就可以将这一部分变为链式调用的代码
1、代码
/**
*
* @param {time,num,type} ops
* @param time 可选,不传默认当前时间,传入可转换时间参数
* @param num 可选 ,默认0,传入减去的时间,1....
* @param type 可选,默认ms,减去时间的单位标准
* @returns Date()
*/
function subtractTime(ops = []) {
const [time = new Date(), num = 0, type = 'ms'] = ops
const Time = new Date(time)
const { ms, s, min, h, date, month, year } = getSeverTime(time)
// ms s min h day week month quarter year
switch (type) {
case 'ms':
Time.setMilliseconds(ms - num)
break
case 's':
Time.setSeconds(s - num)
break
case 'min':
Time.setMinutes(min - num)
break
case 'h':
Time.setHours(h - num)
break
case 'day':
Time.setDate(date - num)
break
case 'week':
Time.setDate(date - num * 7)
break
case 'month':
Time.setMonth(month - num)
break
case 'quarter':
Time.setMonth(month - num * 3)
break
case 'year':
Time.setFullYear(year - num)
break
default:
throw 'error: type is mistake'
}
return Time
}
根据js中this指向取决谁调用,通过这一个操作可以完成链式,将参数变为两个,并将方法挂载到date 实例上,同时时间通过this去获取,如果你想可以自己去尝试一下,我这里需求稍微不一样,所以没做这个处理。
2、效果
使用
subtractTime([, 1, 'day'])
结果
输出时间为今天减1 day,
三、格式化时间
在js中内置对象 Date中是没有一个好的格式化,很难满足需求,不过这个方法其实也不难实现,然而为了这个格式化能够应付各种场景,所以如此实现。
1、代码
/**
* @param {*} time
* Y年(xxxx) M月(xx) D日(xx) k K 数字或中文 w W 英文缩写 或全写 h 时 m分 s秒 ms毫秒
* @param {*} formatStr
* `Y-M-D w h:m:s`
* @return `Y/M/D w h:m:s`
*/
function formatTime(time, formatStr = 'YYYY/MM/DD ww hh:mm:ss') {
const weekStr = [
'星期日',
'星期一',
'星期二',
'星期三',
'星期四',
'星期五',
'星期六',
]
const weekLet = ['Sun.', 'Mon.', 'Tues.', 'Wed.', 'Thurs.', 'Fri.', 'Sat']
const WeekLet = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
]
const { ms, s, min, h, day, date, month, year } = getSeverTime(time)
// Y年(xxxx) M月(xx) D日(xx) k K 数字或中文 w W 英文缩写 或全写 h 时 m分 s秒 ms毫秒
return formatStr
.replace('YYYY', year)
.replace('MM', month + 1)
.replace('DD', date)
.replace('kk', day)
.replace('hh', h)
.replace('mm', min)
.replace('ss', s)
.replace('ms', ms)
.replace('KK', weekStr[day])
.replace('ww', weekLet[day])
.replace('WW', WeekLet[day])
// const timeStr
}
2 、效果
使用
formatTime(subtractTime([, 1, 'day']))
formatTime(subtractTime([, 1, 'day']))
结果
三、规则匹配时间
假如你们有和我一样个需求,这个非常适合,假如说现在有一组数据,后端返回时间戳,而我们前端要根据这个时间与现在时间差距,判断他是昨天,还是前天,啥的,就可以用这个方法。
代码
/**
* 显示时间的rules
* @param {rule,case} rules 匹配规则
* @param {*} time 需要判断的时间
* @param {*} StaTime 基准时间,默认当前时间
* @returns
*/
function showTime(rules, time, StaTime = new Date()) {
time = new Date(time)
console.log(time)
StaTime = new Date(StaTime)
if (!(rules && time)) {
throw 'rules & time can not be empty'
}
if (!Array.isArray(rules)) {
throw 'rules is not Array'
}
if (rules.length === 0) {
return formatTime(time)
}
for (let item of rules) {
if (
item instanceof Function &&
item(time.getTime(), StaTime.getTime())
) {
return item(time.getTime(), StaTime.getTime())
}
if (typeof item.rule === 'boolean') {
if (item.rule) return formatTime(time, item.case)
} else {
const staUpdateStr = subtractTime([
StaTime,
item.rule,
item.type,
]).getTime()
const staStr = subtractTime([StaTime, , item.type]).getTime()
const timeStr = subtractTime([time, , item.type]).getTime()
switch (true) {
case item.rule >= 0 &&
staStr > timeStr &&
staUpdateStr <= timeStr:
return formatTime(time, item.case)
case item.rule <= 0 &&
staStr < timeStr &&
staUpdateStr >= timeStr:
return formatTime(time, item.case)
}
}
}
return formatTime(time)
}
2、效果
使用
匹配规则可以传入如下所有方式
showTime(
[
{ rule: 1, type: 'day', case: '昨天 DD-hh-mm' },
{ rule: -10, type: 'day', case: '明天 DD-hh-mm' },
(time, StaTime) => {
if (time > StaTime) {
return time
}
},
{ rule: 1 > 2, case: 'hh:mm' },
],
'2022/11/14'
)
结果
输出就是,通过输入时间与基准时间经过匹配后的结果,case则是写时间格式,根据上一个方法。
最后
将所有的方法写到内置函数Date的原型上,并封装一个对象export。
通过两种方法使用,这里简单的赋值一下,如果说要做一个方法很多的时间库,那么可能还要在底层进行修改,让函数方法自动可以添加到实例和对象中,这个底层代码可以参考underscore的底层源码。
结尾
简单封装几个时间函数,完成了公司所需要的需求,并保留一个方法做为以后时间函数的基础,如果条件允许可以,开发并递进到前端基建的utils中。