几个原生小函数去掉项目moment.js依赖

moment.js做为一个全球通用库,须要作许多兼容,致使其大而全.在平常项目开发中,每每用不到几个API.我的参与维护的B端项目,组内同事使用其API集中在日期选择组件及先后端日期格式化传递处理上.在项目优化时,经过组内内部约定,采用几个小函数去除moment.js的依赖,可显著减小项目打包体积(moment.min.js 52Kb, moment-with-locales.min.js 327Kb).html

日期/时间格式化展现

在与后端进行数据交接时,后端一般接收/传递2018-10-15 15:34:33形式的标准格式,前端在日期选择组件里展现给用户时,也会采用该格式.定义一个函数将日期对象转换为该类字符返回.前端

export function getDateTime(date = new Date()) {
    let arr = [];
    arr[0] = date.getFullYear();
    arr[1] = date.getMonth() + 1;
    arr[2] = date.getDate();
    arr[3] = date.getHours();
    arr[4] = date.getMinutes();
    arr[5] = date.getSeconds();
    arr = arr.map(item => item < 10 ? `0${item}`:item);
    return `${arr.slice(0,3).join('-')} ${arr.slice(3).join(':)}`;
}
复制代码

后续可经过该标准日期格式,再二次处理得到一些经常使用的格式:git

  • 只须要日期部分: getDateTime(date).slice(0, 10)
  • 只须要时间部分: getDateTime(date).slice(10)/getDateTime(date).slice(-8)
  • 去掉前置的0: getDateTime(date).replace(/([-|:|\s])0/g, "$1")
// 获取标准时间格式hack方法.
export function getDateTime(date = new Date()) {
    const times = date.getTime() - date.getTimezoneOffset() * 6e4;
    return new Date(times).toISOString().slice(0,19).replace('T', ' ');
}

//转换为中文日期时间格式
const cn = ['年', '月','日 ', '时', '分', '秒'];
const ret = getDateTime(date).split(/[-:\s]/).map((val, index) => +val + cn[index]).join('');
复制代码

标准日期格式转换为Date对象

从接口获取到时间字符串,须要转换为日期对象进行后续的区间计算等操做,如计算昨天,今天,近一周,近一个月.github

export function toDate(string) {
    const args = string.split(/[\-:\s]/);
    args[1] -= 1;
    return new Date(...args);
}
// 这里有隐性转换, '09' 经过减法运算或给Date()构造函数传递多参数,会转整.
// 若是是ES5,这里spread运算符怎么写? https://babeljs.io/en/repl.html
复制代码

日期区间计算

在订单查询等业务中,常常会提供今天,昨天,近一周,近一个月等便捷日期选择查询方式,前端须要根据当前日期结合用户操做,转换为后端须要的时间格式进行查询操做.后端

对于天/时/分/秒,能够加减相应的秒数来处理.babel

const ONE_DAY = 86400000;
export function getOffsetDay(offset = 0, date = new Date()) {
    const seconds = date.getTimes();
    const days = new Date(seconds + ONE_DAY * offset);
    return getDateTime(days).slice(0, 10);
}
复制代码

对于月份,计算秒数较复杂,能够利用setMonth来简便处理.不过须要考虑天然月逻辑(7/31减一个月是6/30,而不是7/1(6/31)).less

export function getOffsetMonth(offset = 0, date = new Date()) {
    const year = date.getFullYear();
    const month = date.getMonth();
    const day = date.getDate();
    //can add if day >28 for less cacl monthlastday
    const monthLastDay = new Date(new Date(year, month+1 + offset, 1, 1) - ONE_DAY).getDate();
    if (day > monthLastDay) date.setDate(monthLastDay);
    date.setMonth(month + offset);
    return getDateTime(date).slice(0, 10);
}
复制代码

日期比较

日期转换为上面的标准字符格式后,能够直接采用字符串来比较(早于,晚于,等于).日期对象可显式转换为毫秒数(date.getTime()) 或 隐式(调valueOf())来进行比较. 特定区间的日期比较,则能够用上面的函数将日期字符转换为日期对象,加减相应的毫秒数后再用简单的比较方式处理.函数

notice

  • date.set**相关函数会有相应的进位处理.
  • date.set**返回值为设置后日期对象的时间戳
  • new Date(string) 底层是调用的Date.parse().格式为RFC 2822 或 ISO 8601,具体见MDN连接
  • new Date(...args) 多参数时,调用的是Date.UTC()
  • new Date(...args) 多参数(2 ~ 7)传递时,当省略相关参数时,采用默认值(0 or 1),而非当前本地时间对应值.
  • 直接采用函数方式调用Date(),返回当前时间的字符串形式,忽略传递的参数.
  • date.toGMTString()正在弃用,建议使用toUTCString()替代.两者有闰秒之差?
  • date.getTimezoneOffset()返回的是当前本地时间与UTC时间相差的分钟数
  • date.toJSON返回toISOString字符串,用JSON.stringify深拷贝对象时须要将时间字符转换回来.

文章推荐

developer.mozilla.org/en-US/docs/…优化

GitHub勘误/交流: github.com/pagemarks/c…ui

相关文章
相关标签/搜索