Date杂谈

工作中,经常会需要处理时间!刚开始的时候是使用moment插件,非常强大的一款插件,能够满足工作需求。但是,随着项目的不断扩展,就需要对项目进行一些“瘦身”,基于“杀鸡焉用牛刀”的想法,就自己动手写了一些帮助函数,目前基本能够满足平时工作的需要。
先来看看写的代码的运行效果

  1. DateUTC,用于生成一个Date对象

    《Date杂谈》 image.png

    可能大家会比较奇怪,已经有new Date()方法,为什么还要写一个用法一直的DateUTC方法,来看下面的

    《Date杂谈》 image.png

new Date(‘2018-04-01’)得到的时间是早上8点而不是0点,这是因为本地时间和格林威治时间有一个时间差。getTimezoneOffset返回时间差。所以用一个函数DateUTC来对Date做了一层封装

function DateUTC (date) {
  let isDate = (typeof date === 'object') && (date instanceof Date)
  if (isDate) return date
  let localDate
  try {
    localDate = date === undefined ? new Date() : new Date(date)
  } catch (e) {
    console.error(e)
  }
  if (date && /^\d{4}(-\d{2}){0,2}$/.test(date)) {
    let timeZoneOffset = localDate.getTimezoneOffset()
    let utcTimeStamp = localDate.getTime() + timeZoneOffset * 60 * 1000
    return new Date(utcTimeStamp)
  }
  return localDate
}

工作中,我们可能经常会有这样子的场景,比如在选择时间段的时候,需要取今后的某个时间段。比如,判断两个日期的时间差,以及以固定的格式展示时间等等。个人手写了以下一些代码,运行结果如图

《Date杂谈》 image.png
《Date杂谈》 image.png

最后一个dateSpec(好吧,我承认方法名不太好)方法,是集合以上代码的功能。包括格式化,计算时间差值,获取某个日期之后(前)的一个时间。运行结果如图

《Date杂谈》 image.png

以下是全部完整的代码

/**
 * @param {*} date
 * test
 * let aa = ['2018', '2018-', '2018-01', '2018-01-', '2018-1', '2018-01-02', '2018-01-2', '2018-1-2', '2018-01-2 6:', '2018-01-2 6:2', '2018-01-2 6:2:2']
 * aa.forEach(a => console.log(a, reg.test(a), dateSpec(a, 'yyyy-MM-dd HH:mm:ss')))
 */


function leftPad(item) {
  return item.toString().length < 2 ? ('0' + item) : item
}


function getTimeStampUnit (unit) {
  switch (unit) {
    case 'day':
      return 1000 * 3600 * 24
    case 'hour':
      return  1000 * 3600
    case 'minute':
      return 1000 * 60
    case 'second':
      return 1000
      break
    default:
      return 1
  }
}

// 用法如Date
 function DateUTC (date) {
  let isDate = (typeof date === 'object') && (date instanceof Date)
  if (isDate) return date
  let localDate
  try {
    localDate = date === undefined ? new Date() : new Date(date)
  } catch (e) {
    console.error(e)
  }
  if (date && /^\d{4}(-\d{2}){0,2}$/.test(date)) {
    let timeZoneOffset = localDate.getTimezoneOffset()
    let utcTimeStamp = localDate.getTime() + timeZoneOffset * 60 * 1000
    return new Date(utcTimeStamp)
  }
  return localDate
}
/**
 * 
 * @param {*} time1 a Date object or Date params
 * @param {*} time2 a Date object or Date params
 * @param {*} unit can be one of ['year', 'month', 'day', 'hour', 'minute', 'second']
 */
 function diff (time1, time2, unit='day') {
  let date1 = DateUTC(time1)
  let date2 = DateUTC(time2)
  if (unit === 'year') {
    return date2.getFullYear() - date1.getFullYear()
  }
  if (unit === 'month') {
    return date2.getMonth() - date1.getMonth()
  }
  let timeStampUnit = getTimeStampUnit(unit)
  return parseInt((date2.getTime() - date1.getTime()) / timeStampUnit)
}

/**
 * 
 * @param {*} date a Date object or Date params
 * @param {*} diff 
 * @param {*} unit can be one of ['year', 'month', 'day', 'hour', 'minute', 'second']
 * for example: dateFrom('2012-02-29', 12, 'month') // Fri Mar 01 2013 00:00:00 GMT+0800 (CST)
 */
 function dateFrom(time, diff, unit='day') {
  let date = DateUTC(time)
  if (unit === 'year') {
    let year =  date.getFullYear() + diff
    return DateUTC(date.setFullYear(year))
  }
  if (unit === 'month') {
    let month = date.getMonth() + diff
    return DateUTC(date.setMonth(month))
  }
  let timeStampUnit = getTimeStampUnit(date.getTime())
  return DateUTC(timeStampUnit + diff * timeStampUnit)
}

 function format (date, form = 'yyyy-MM-dd') {
  date = DateUTC(date)
  if (!form) return date
  let year = date.getFullYear()
  let month = leftPad(date.getMonth() + 1)
  let day = leftPad(date.getDate())
  let hours = leftPad(date.getHours())
  let minutes = leftPad(date.getMinutes())
  let seconds = leftPad(date.getSeconds())
  return form.replace('yyyy', year).replace('MM', month).replace('dd', day).replace('HH', hours).replace('mm', minutes).replace('ss', seconds)
}
/**
 * use it just like how you new a Date and the second value is the format
 *  if you don't want to format it, set the form to false
 * @param {*} value any params can new a Date
 * @param {*} form 
 * @param {*} UTC 
 */
 function dateSpec (payload) {
  if (payload === undefined) return DateUTC()
  if (!payload) {
    console.error(`error params, the params is an object lise this { form: 'yyyy-MM-dd', diff: 0, unit: 'day', date: '2018-11-19' }`)
  }
  let { form = 'yyyy-MM-dd', diff = 0, unit = 'day', date = undefined } = payload
  let time = date === undefined ? DateUTC() : DateUTC(date)
  diff && (time = dateFrom(time, diff, unit))
  return form ? format(time, form) : time
  // let rs = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds
}




// test
if (true || __DEV__) {
  var arr = ['2018', '2018-', '2018-01', '2018-01-', '2018-1', '2018-01-02', '2018-01-2', '2018-1-2', '2018-01-2 6:', '2018-01-2 6:2', '2018-01-2 6:2:2']
  console.log(`\n---dateSpec(date, 'yyyy-MM-dd HH:mm:ss')---\n`)
  arr.forEach(a => console.log(`\ndateSpec({date: ${a}, form: 'yyyy-MM-dd HH:mm:ss'}))\n`, a, ':  ', dateSpec({date: a, form: 'yyyy-MM-dd HH:mm:ss'})))

  console.error('\n----DateUTC,用法和Date一致 ----\n')
    console.log(`DateUTC([2016, 7]): `, DateUTC([2016, 7]))
    console.log(`DateUTC(): `, DateUTC())
    console.log(`DateUTC('2019-5-10'): `, DateUTC())

  console.error(`format (date, form = 'yyyy-MM-dd') 格式化时间`)
    console.log(`format('2018-1', 'HH:mm:ss yyyy/MM/dd'):  `, format('2018-1', 'HH:mm:ss yyyy/MM/dd'))

  console.error('\n\n----diff:取两个时间的差值(可以选择按照年、月、日、时、分、秒为单位)----\n\n')
    console.log(`\ndiff('2014-10-13', '2018-11-15')\n`, 'diff day', diff('2014-10-13', '2018-11-15'))
    console.log(`\ndiff('2014-10-13', '2018-11-15', 'year')\n`, 'diff year', diff('2014-10-13', '2018-11-15', 'year'))
    console.log(`\ndiff('2014-10-13', '2018-11-15', 'month')\n`, 'diff month',diff('2014-10-13', '2018-11-15', 'month'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'hour')\n`, 'diff hour', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'hour'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'minute')\n`, 'diff minute', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'minute'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'second')\n`, 'diff second', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'second'))

  console.error(`\n\n----dateFrom(time, diff, unit='day') :取与time间隔diff的时间(可以选择按照年、月、日、时、分、秒为单位)----\n\n`)
    console.log(`\ndiff('2014-10-13', '2018-11-15')\n`, 'diff day', diff('2014-10-13', '2018-11-15'))
    console.log(`\ndiff('2014-10-13', '2018-11-15', 'year')\n`, 'diff year', diff('2014-10-13', '2018-11-15', 'year'))
    console.log(`\ndiff('2014-10-13', '2018-11-15', 'month')\n`, 'diff month',diff('2014-10-13', '2018-11-15', 'month'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'hour')\n`, 'diff hour', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'hour'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'minute')\n`, 'diff minute', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'minute'))
    console.log(`\ndiff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'second')\n`, 'diff second', diff('2018-01-02 06:02:00', '2018-01-04 07:22:10', 'second'))

  console.error(`\n----dateSpec: ----\n
    1. 获取某个时间date, {date: '2019-8-11'},默认为当天\n
    1. 格式化时间, {form: 'yyyy-MM-dd HH:mm:ss'},默认为yyyy-MM-dd格式\n
    1. 获取距离date之前或之后的某个时间(diff: 时间差, unit:单位(可以是年月日时分秒)), {diff: -4, unit: 'hour'},unit默认为day\n`)
    console.log('\ndateSpec()\n', 'today: ', dateSpec())
    console.log('\ndateSpec({})\n', 'today: ', dateSpec({}))
    console.log(`\ndateSpec({form: 'HH:mm:ss yyyy/MM/dd'})\n`, 'today: ', dateSpec({form: 'HH:mm:ss yyyy/MM/dd'}))
    console.log(`\ndateSpec({diff: -3})\n`, 'three days ago: ', dateSpec({diff: -3}))
    console.log(`\ndateSpec({diff: 3, unit: 'month'})\n`, 'three month later: ', dateSpec({diff: 3, unit: 'month'}))
    console.log(`\ndateSpec({diff: 1, unit: 'year'})\n`, 'one year later: ', dateSpec({diff: 1, unit: 'year'}))
    console.log(`\ndateSpec({diff: -1, unit: 'hour', form: 'HH:mm:ss yyyy/MM/dd'})\n`, 'one hour ago: ', dateSpec({diff: -1, unit: 'hour', form: 'HH:mm:ss yyyy/MM/dd'}))
    console.log(`\ndateSpec({diff: -20, unit: 'minute', form: 'HH:mm:ss yyyy/MM/dd'})\n`, '20 minute ago: ', dateSpec({diff: -20, unit: 'minute', form: 'HH:mm:ss yyyy/MM/dd'}))
    console.log(`\ndateSpec({diff: 100, unit: 'second', form: 'HH:mm:ss yyyy/MM/dd'})\n`, '100 second later: ', dateSpec({diff: 100, unit: 'second', form: 'HH:mm:ss yyyy/MM/dd'}))

}

为了更好的展示输出结果,所以用了一个console.error来分割

以上

    原文作者:pixels
    原文地址: https://www.jianshu.com/p/1c24266dafae
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞