前端开发中常用的时间处理函数

/**
 * 字符串填充「0」
 * @param {string} origin 原始字符串
 * @param {number} length 目标字符串长度
 * @param {boolean} isFillBack 是否从尾部跳槽
 * @returns {string} 处理后的字符串
 */
export function fillZero (origin, length, isFillBack) {
  length = origin.length > length ? origin.length : length // 若原长度比目标长度更长
  if (isFillBack) {
    return (origin.toString() + new Array(length).join("0")).substr(0, length)
  } else {
    return (new Array(length).join("0") + origin.toString()).substr(-length)
  }
}

/**
 * 比较数字大小补0
 * *compareFillZero(5) => '05'
 * *compareFillZero(25,1000) => '025'
 * @param {Number|String} num 数字
 * @param {number|String} maxNum 比较的数字
 * @param {String} fillUnit 默认0,可其他字符串*,-等
 * @returns {string} 补0后的字符串
 */
export function compareFillZero (num, maxNum = 100, fillUnit = '0') {
  if (!num && +num !== 0) return ''
  let numString = `${num}`
  if (+num < +maxNum) {
    for (let i = 1; i < String(maxNum).length - String(num).length; i++) {
      numString = fillUnit + numString
    }
  }
  return numString
}


/**
 * 时间类型兼容,兼容「时间戳数字」「时间戳字符串」和「时间对象」
 * @param {string|number|object} time 时间内容,可传入时间对象,或时间戳
 * @param {string} type 期望返回的数据类型
 * @returns {string|object} 时间对象或时间戳
 */
export function dealTime(time, type = 'string') {
  if(!time) {
    return type = 'string' ? "" : null
  }
  if (time.toString().indexOf('/') > 0 || time.toString().indexOf('-') > 0) {
    time = new Date(time)
  } else if (typeof time === 'string' || typeof time === 'number') {
    const standTimeStampLength = 13 // 标准时间戳长度
    time = fillZero(time, standTimeStampLength, true) // 转化为标准的13位时间戳
    time = new Date(parseInt(time))
  }
  if (type === 'object') {
    return time
  } else if (type === 'string') {
    return time.getTime()
  }
}

/**
 * 格式化时间
 * @param {string|number|object} date 时间内容,可传入时间对象,或时间戳
 * @param {string} formatStr 格式模板
 * @returns {string} 处理后的字符串
 */
export function formatTime(date, formatStr = 'YYYY-MM-DD hh:mm:ss') {
  if(!date) {
    return ""
  }
  date = dealTime(date, 'object')
  const formatType = {
    Y: date.getFullYear(),
    M: date.getMonth() + 1,
    D: date.getDate(),
    h: date.getHours(),
    m: date.getMinutes(),
    s: date.getSeconds(),
  }
  return formatStr.replace(
    /Y+|M+|D+|h+|m+|s+/g,
    target => (new Array(target.length).join('0') + formatType[target[0]]).substr(-target.length)
  )
}

/**
 * 判断给出的时间是否已经过期
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否过期
 */
export function isOverdue(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  return timestamp < new Date().getTime()
}

/**
 * 获取最近几天的时间范围
 * @param {number} length 天数,最近的几天
 * @param {string|number|object} [date] 截止时间,默认为今天
 * @returns {array} 解析好之后的时间戳范围数组
 */
export function getLastSomeDay(length, date = new Date()) {
  date = dealTime(date, 'object')
  const startTime = new Date(date.getFullYear(), date.getMonth(), date.getDate() - length)
  const endTime = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 0, 0, -1)
  return [startTime.getTime(), endTime.getTime()]
}

/**
 * 获取某月的时间戳范围
 * @param {string|number|object} [date] 特定格式化的时间
 * @returns {array} 解析好之后的时间戳范围
 */
 export function getMonthRange(date = new Date()) {
  date = dealTime(date, 'object')
  const startTime = new Date(date.getFullYear(), date.getMonth(), 1)
  const endTime = new Date(date.getFullYear(), date.getMonth() + 1, 1, 0, 0, -1)
  return [startTime.getTime(), endTime.getTime()]
}

/**
 * 获取某周的时间戳范围
 * @param {string|number|object} [date] 特定格式化的时间
 * @returns {array} 解析好之后的时间戳范围
 */
export function getWeekRange(date = new Date()) {
  date = dealTime(date, 'object')
  const daysInWeek = 7
  const day = date.getDay()
  // Date.prototype.getDay() 的返回值为 0-6,0 表示周日
  const week = day === 0 ? 6 : day - 1
  const startTime = new Date(date.getFullYear(), date.getMonth(), date.getDate() - week)
  const endTime = new Date(
    date.getFullYear(),
    date.getMonth(),
    (daysInWeek - week) + date.getDate(),
    0,
    0,
    -1,
  )
  return [startTime.getTime(), endTime.getTime()]
}

/**
 * 获取某日的时间戳范围
 * @param {string|number|object} [date] 特定格式化的时间
 * @returns {array} 解析好之后的时间戳范围
 */
export function getDayRange(date = new Date()) {
  date = dealTime(date, 'object')
  const startTime = new Date(date.getFullYear(), date.getMonth(), date.getDate())
  const endTime = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 0, 0, -1)
  return [startTime.getTime(), endTime.getTime()]
}

/**
 * 获取时间提示信息
 * @param {string|number|object} timestamp 需要转换的时间戳
 * @returns {string} 解析好之后时间提示
 */
export function getDateTips(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const now = date.getTime()
  // eslint-disable-next-line
  const fiveMinuteBefore = new Date().setMinutes(date.getMinutes() - 5)
  const oneHourBefore = new Date().setHours(date.getHours() - 1)
  const today = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()
  const yesterday = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1).getTime()
  const twoDaysBefore = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 2).getTime()
  if (timestamp > fiveMinuteBefore) { // 5分钟内
    return '刚刚'
  } else if (timestamp > oneHourBefore) { // 60分钟内
    return `${Math.floor((now - timestamp) / 1000 / 60)}分钟前`
  } else if (timestamp > today) { // 今天
    return `今天 ${formatTime(timestamp, 'hh时mm分')}`
  } else if (timestamp > yesterday) { // 昨天
    return `昨天 ${formatTime(timestamp, 'hh时mm分')}`
  } else if (timestamp > twoDaysBefore) { // 前天
    return `前天 ${formatTime(timestamp, 'hh时mm分')}`
  } else { // 更久之前
    return formatTime(timestamp, 'MM月DD日 hh时mm分')
  }
}

/**
 * 是否是今天
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否是今天
 */
export function isToday(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const timeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()
  const timeEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).getTime()
  return timeStart <= timestamp && timestamp < timeEnd
}

/**
 * 是否是明天
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否是明天
 */
export function isTomorrow(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const timeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).getTime()
  const timeEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 2).getTime()
  return timeStart <= timestamp && timestamp < timeEnd
}

/**
 * 是否是后天
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否是后天
 */
export function isTheDayAfterTomorrow(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const timeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 2).getTime()
  // eslint-disable-next-line
  const timeEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 3).getTime()
  return timeStart <= timestamp && timestamp < timeEnd
}

/**
 * 是否是昨天
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否是昨天
 */
export function isYesterday(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const timeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1).getTime()
  const timeEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime()
  return timeStart <= timestamp && timestamp < timeEnd
}

/**
 * 是否是前天
 * @param {string|number|object} timestamp 给出的时间戳或时间对象
 * @returns {boolean} 是否是前天
 */
export function isTheDayBeforeYesterday(timestamp) {
  timestamp = dealTime(timestamp, 'string')
  const date = new Date()
  const timeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 2).getTime()
  const timeEnd = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1).getTime()
  return timeStart <= timestamp && timestamp < timeEnd
}

/**
 * 获取日期对应的星期数
 * @param {string|number|object} date 给出的时间戳或时间对象
 * @returns {string} 日期
 */
export function getWeek(date) {
  date = dealTime(date, 'object')
  return ['日', '一', '二', '三', '四', '五', '六'][date.getDay()]
}

/**
 * 是否在同一个时间段内
 * @param {string|number|object} time1 时间1
 * @param {string|number|object} time2 时间2
 * @param {string} timeType 时间段类型
 * @returns {boolean} 是否在同一个时间段内
 */
export function isSame(time1, time2, timeType) {
  const formatStr = {
    year: 'YYYY',
    month: 'YYYY:MM',
    day: 'YYYY:MM:DD',
    hour: 'YYYY:MM:DD hh',
    minute: 'YYYY:MM:DD hh:mm',
    second: 'YYYY:MM:DD hh:mm:ss',
  }[timeType]
  return formatTime(time1, formatStr) === formatTime(time2, formatStr)
}

/**
 * 转化时间长度
 * @param {number} time 时间长度
 * @param {string} type 转换类型
 * @returns {number} 转换后的数值
 */
export function getTimeLength(time, type) {
  time = parseInt(time)
  return time / {
    day: 24 * 60 * 60 * 1000,
    hour: 60 * 60 * 1000,
    minute: 60 * 1000,
    second: 1000,
  }[type]
}

/**
 * 获取当前月共有多少天
 * @param {Date} date 日期对象
 */
export function getMonthDays(date = new Date()) {
  const dateString = dealTime(date, 'object').toISOString()
  const clonedDate = new Date(dateString)
  clonedDate.setDate(1)
  clonedDate.setMonth(clonedDate.getMonth() + 1)
  clonedDate.setDate(0)
  return clonedDate.getDate()
}

/**
 * 获取多少个月后的今天
 * @param {Date} date 当前日期
 * @param {number} months 月数,表示多少个月后
 */
export function afterMonths(date, months) {
  const dateString = dealTime(date, 'object').toISOString()
  date = new Date(dateString) // 防止直接修改外部传进来的 Date 对象
  const dayOfMonth = date.getDate()
  date.setDate(1)
  date.setMonth(date.getMonth() + months)
  const newDayOfMonth = Math.min(dayOfMonth, getMonthDays(date))
  date.setDate(newDayOfMonth)
  return date
}

/**
 * 时间距离,相距多少天
 * @param {string|number|object} time1 时间1
 * @param {string|number|object} time2 时间2
 * @param {string} timeType 时间段类型
 * @returns {number} 时间距离
 */
export function getDateSpace(time1, time2, timeType = 'day') {
  let formatStr = {
    day: 'YYYY/MM/DD ',
    hour: 'YYYY/MM/DD hh',
    minute: 'YYYY/MM/DD hh:mm',
    second: 'YYYY/MM/DD hh:mm:ss',
  }[timeType]
  time1 = new Date(formatTime(time1, formatStr))
  time2 = new Date(formatTime(time2, formatStr))
  return getTimeLength(time1.getTime() - time2.getTime(), timeType)
}

/**
 * 毫秒转时间 formatDuration(34325055574); // '397天,6小时,44分钟,15秒
 * @param {string|number} ms 时间(毫秒)
 * @param {string} unit 时间间隔符号 , -
 * @param {string} lang 时间单位语言 zh/en
 * @returns {string} 时间段
 */
export function formatDuration(ms, unit = '',lang="zh") {
  if (ms < 0) ms = -ms
  const langMap = {
    day:{
      zh:"天",
      en:"day",
    },
    hour:{
      zh:"时",
      en:"hour",
    },
    minute:{
      zh:"分",
      en:"minute",
    },
    second:{
      zh:"秒",
      en:"second",
    },
    millisecond:{
      zh:"毫秒",
      en:"millisecond",
    },
  }
  const time = {
    [langMap.day[lang]]: Math.floor(ms / 86400000),
    [langMap.hour[lang]]: Math.floor(ms / 3600000) % 24,
    [langMap.minute[lang]]: Math.floor(ms / 60000) % 60,
    [langMap.second[lang]]: Math.floor(ms / 1000) % 60,
    // [langMap.millisecond[lang]]: Math.floor(ms) % 1000
  }
  return Object.entries(time)
    .filter(val => {
      const isSecond  = val[0]===langMap.second[lang]
      const isMin  = val[0]===langMap.minute[lang]
      // 保留0秒的情况
      if(val[1] !== 0 || isSecond){
        return val
      }
      // 保留0分的情况
      if(val[1] !== 0 || isMin){
        return val
      }
    })
    .map(([key, val]) => `${compareFillZero(val)}${key}${(val !== 1 && lang==='en') ? 's' : ''}`)
    .join(unit)
}

/**
 * 格式化倒计时 大于一天显示“1天”,小于一天的显示'23:00:00'格式
 * @param {string|number} ms 时间(毫秒)
 * @param {string} showFormat 显示格式,number: 12:12:10, chinese: 12时12分12秒
 * @returns {string} 时间段
 */
 export function formatCountDown(ms,showFormat = "number") {
  if (ms < 0) {
    ms = -ms
  }
  const oneDayTime = 8.64e7 // 一天的时间毫秒
  if (ms > oneDayTime) {
    // 向下取整,24小时~48小时内都算1天
    return `${Math.floor(ms / oneDayTime)}天`
  } else {
    let hour = Math.floor(ms / 3600000)
    let minute = Math.floor(ms / 60000) % 60
    let second = Math.floor(ms / 1000) % 60

    hour = hour < 10 ? `0${hour}` : hour
    minute = minute < 10 ? `0${minute}` : minute
    second = second < 10 ? `0${second}` : second
    return showFormat === 'number' ? `${hour}:${minute}:${second}` : `${hour} 时 ${minute} 分 ${second} 秒`
  }
}

/**
 * 判断time是否在时间范围(时分)内
 * @param {String} time 判断的时间戳
 * @param {Array} 时间区间数组
 *        {String} beginTime 开始时间 19:40
 *        {String} endTime 结束时间 23:59 (当天) | 08:00 (次日)
 * @returns {Boolean}
 */
 export function inTimeRange(time,[beginTime, endTime]){
  let strb = beginTime.split(':')
      if (strb.length !== 2) {
        return false
      }
      let stre = endTime.split(':')
      if (stre.length !== 2) {
        return false
      }
      let b = new Date(time)
      let e = new Date(time)
      let n = new Date(time)
      b.setHours(strb[0])
      b.setMinutes(strb[1])

      if (stre[0] < strb[0]) {
        e.setDate(e.getDate() + 1)
      }
      e.setHours(stre[0])
      e.setMinutes(stre[1])
      return n.getTime() - b.getTime() > 0 && n.getTime() - e.getTime() < 0
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值