格式化日期(每天看开源项目学一招半式)

290 阅读1分钟

开源项目链接地址

代码如下

function formatType(type, format, value, regExpAttributes) {
  const regExpMap = {
    year: '(Y+)',
    month: '(M+)',
    date: '(D+)',
    hour: '(h+)',
    minute: '(m+)',
    second: '(s+)',
    quarter: '(q+)',
    millisecond: '(S)'
  }

  if (new RegExp(regExpMap[type], regExpAttributes).test(format)) {
    const replaceStr = type === 'year'
                       ? value.toString().substr(4 - RegExp.$1.length)
                       : (RegExp.$1.length === 1) ? value : pad(value)
    format = format.replace(RegExp.$1, replaceStr)
  }

  return format
}

function pad(value) {
  return ('00' + value).substr(('' + value).length)
}

function formatDate(date, format) {
  const map = {
    year: {
      value: date.getFullYear(),
      regExpAttributes: 'i'
    },
    month: {
      value: date.getMonth() + 1
    },
    date: {
      value: date.getDate(),
      regExpAttributes: 'i'
    },
    hour: {
      value: date.getHours(),
      regExpAttributes: 'i'
    },
    minute: {
      value: date.getMinutes()
    },
    second: {
      value: date.getSeconds()
    },
    quarter: {
      value: Math.floor((date.getMonth() + 3) / 3),
      regExpAttributes: 'i'
    },
    millisecond: {
      value: date.getMilliseconds()
    }
  }

  for (const key in map) {
    format = formatType(key, format, map[key].value, map[key].regExpAttributes)
  }

  return format
}

测试

console.log(
  'result:',
  formatDate(new Date(), 'YYYY.MM.DD hh:mm')
)

演绎过程

根据传入日期对象参数,获得对应的月份7, 根据匹配规则YYYY.MM.DD hh:mm, 通过正则(M+)找出MM, 接着把7替换MM, 同时使用pad函数处理下7 => 07, 24 => 24情况,以此类推。

补零pad

function pad(value) {
  return ('00' + value).substr(('' + value).length)
}

如果值1位数7, 前面加00, 即007, 剪掉0, 即07

如果值2位数24, 前面加00, 即0024, 剪掉00, 即24

共同点,剪掉的是值的长度。

数字 + 字符串,一定是字符串相加,不是数字的累加,这点要注意。

GITHUB仓库,欢迎Star