如何自己封装一个time库

133 阅读2分钟
利用Date封装额外功能的time库

本文使用类创建,主要考虑业务层面,如果使用函数,每次使用都会生成一个新的Date对象,如果大量使用会导致内存大量消耗,主要考虑性能问题,所以选择class

  1. 时间格式化format():利用 Date 的格式化共功能,
export class Time {
    date: Date;
    constructor(date = new Date()) {
        this.date = date;
    }
    format(pattern = 'YYYY-MM-DD') {
        // 目前支持的格式有 YYYY MM DD HH mm ss SSS
        const year = this.date.getFullYear()
        const month = this.date.getMonth() + 1
        const day = this.date.getDate()
        const hour = this.date.getHours()
        const minute = this.date.getMinutes()
        const second = this.date.getSeconds()
        const msecond = this.date.getMilliseconds()
        return pattern.replace(/YYYY/g, year.toString())
            .replace(/MM/, month.toString().padStart(2, '0'))
            .replace(/DD/, day.toString().padStart(2, '0'))
            .replace(/HH/, hour.toString().padStart(2, '0'))
            .replace(/mm/, minute.toString().padStart(2, '0'))
            .replace(/ss/, second.toString().padStart(2, '0'))
            .replace(/SSS/, msecond.toString().padStart(3, '0'))
    }
  1. 获取当前月的第一天firstDayOfMonth()
firstDayOfMonth() {
        return new Time(new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0));
}
  1. 获取当前这年的第一天firstDayOfYear()
firstDayOfYear() {
        return new Time(new Date(this.date.getFullYear(), 0, 1, 0, 0, 0));
    }
  1. 获取当前月的最后一天lastDayOfMonth()
lastDayOfMonth() {
        return new Time(new Date(this.date.getFullYear(), this.date.getMonth() + 1, 0, 0, 0, 0));
    }
  1. 获取当前这年的最后一天lastDayOfYear()
lastDayOfYear() {
        return new Time(new Date(this.date.getFullYear() + 1, 0, 0, 0, 0, 0));
    }
  1. 时间相加功能,即下个月,明天,明年等 add(),此API接受两个参数,第一个为相差数,类型为number,第二个参数为相差的类型,类型为年月日等,例:
// 明年、下个月
add(1,year)
add(1,month)

此API可接受负数,即为上个月,去年等,例:

// 上个月
add(-1,month)

需要注意的是,当进行月份相加时,会有一些隐藏的问题,JS的Date对象进行month加减时,标准是当前月的天数,因为每个月天数不一样,就会导致一个问题,当一月31号加一个月会变成3月2号,与我们的思维不太一样,那么需要进行比较,思路主要是,拿当前月的天数和下个月的天数进行比较,取小的一个进行setDate,代码如下:

add(amount: number, unit: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond') {
        // return new Time but not change this.date
        let date = new Date(this.date.getTime());
        switch (unit) {
            case 'year':
                date.setFullYear(date.getFullYear() + amount);
                break;
            case 'month':
                const d = date.getDate()
                date.setDate(1)
                date.setMonth(date.getMonth() + amount);
                const d2 = new Date(date.getFullYear(), date.getMonth() + 1, 0, 0, 0, 0).getDate()
                date.setDate(Math.min(d, d2))
                break;
            case 'day':
                date.setDate(date.getDate() + amount);
                break;
            case 'hour':
                date.setHours(date.getHours() + amount);
                break;
            case 'minute':
                date.setMinutes(date.getMinutes() + amount);
                break;
            case 'second':
                date.setSeconds(date.getSeconds() + amount);
                break;
            case 'millisecond':
                date.setMilliseconds(date.getMilliseconds() + amount);
                break;
            default:
                throw new Error('Time.add: unknown unit');
        }