写这篇文章主要原因是昨天看了这篇《JS实用小方法-将时间转换为
刚刚
、几秒前
、几分钟前
、几小时前
、几天前
、几月前或按照传入格式显示》文章,就想自己也写一下,看看最终能写成怎么样?(各位见笑了)。主要想着以函数的单⼀职责原则(SRP)结构化编程强调单⼀出⼝的原则写的,和原作者的函数还是有点不一样的。
评论区问题:Infinity 问题已修复
请小二上菜
定义参数
- 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}前`;
}
}
}