JS实用小方法:将时间转换为`刚刚`、`几秒前`、`几分钟前`、`几年前`.....

1,323 阅读2分钟

写这篇文章主要原因是昨天看了这篇《JS实用小方法-将时间转换为 刚刚几秒前几分钟前几小时前几天前、几月前或按照传入格式显示》文章,就想自己也写一下,看看最终能写成怎么样?(各位见笑了)。

主要想着以函数的单⼀职责原则(SRP)结构化编程强调单⼀出⼝的原则写的,和原作者的函数还是有点不一样的。

评论区问题:Infinity 问题已修复

请小二上菜

image.png

定义参数

  • date: 传入的参数

时间处理规则

标题时间
刚刚0
秒前1000
几分钟前60 * 1e3
几小时前3600 * 1e3
几天前24 * 3600 * 1e3
几月前30 * 24 * 3600 * 1e3
几年前365 * 24 * 3600 * 1e3

提示

1e3 是1000的缩写

3600 是一个小时(60分钟 * 60秒/h)

思考需要注意的问题

  • [ ✓ ] 常规思维下,传入的应该是一个过去的有效时间
  • [ ✓ ] 也有可能传入一个将来的时间点
  • [ ✓ ] 或者传入的 date 并不一定是一个有效的时间,误传了一个中文字符串等等

创建函数

/**
 * 函数接收一个日期作为参数,并返回一个字符串
 * @param {Date|String} date 需要计算时间间隔的日期
 * @return String
 */
function timeIntervalFormat(date) {
      let t, p, l = [
        { n: '年', s: 3600 * 24 * 365 * 1e3 },
        { n: '个月', s: 3600 * 24 * 30 * 1e3 },
        { n: '天', s: 3600 * 24 * 1e3 },
        { n: '小时', s: 3600 * 1e3 },
        { n: '分钟', s: 60 * 1e3 },
        { n: '秒', s: 1 * 1e3 },
        { n: '刚刚', s: 0 }
      ];
      t = Date.now() - new Date(date || Date.now()).getTime()

      // 考虑传入的并不是一个可以被Date对象解析的日期字符串,避免错误影响程序运行
      if (Number.isNaN(t)) return ''
      if (t === 0) return l.find(e => e.s === t).n;

      t < 0 ? ((p = !!t), (t = -t)) : (p = !1)

      for (let i = 0; i < l.length; i++) {
        const { n, s } = l[i]
        if (s === 0) return '刚刚'
        else if (t >= s) {
          const v = Math.floor(t / s)
          return p ? `未来${v}${n}` : `${v}${n}前`;
        }
      }
    }