前言
不管是在博客类、新闻类项目中都必定少不了时间的展示,例如:炉石新闻页、掘金用户主页的动态展示
在对时间上要求比较高得情况下,我们自己写肯定就不太行了,毕竟自己手搓得话一方面是收益和成本不一致(手写计算有些时间考虑不了很全:闰年、二月、大小月…)、另外市面上都有很成熟的第三方库了,提供的方法还能覆盖更多的场景。干嘛不适用呢?接下来我就以dayjs
这个库来完成一样的效果…
插曲
在实现这个功能之前,我先讲讲自己的经历吧,也就是我为什么会了解这方面🤣接触这个我也是因为之前在开发某项目有这个功能,而组内其他项目又正好有这个功能,mt
也让我直接复用,结果这一复用就给后面埋下了坑。这是之前复用的代码,这个代码中对大小月、二月、闰年就没有考虑,导致后面出现了两次问题。
// 获取包含时间信息的所有元素
const elements = document.querySelectorAll('.list-time')
// 遍历每个元素
elements.forEach(function (element) {
// 获取data-time属性的值
const timeString = element.getAttribute('data-timestamp')
// eslint-disable-next-line
const date = new Date(parseInt(timeString, 10));
const currentDate = new Date()
const timeDiff = currentDate.getTime() - date.getTime()
const dayDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
const today = 0
const beforeDay = 1
const beforeMonth = 30
const beforeYear = 365
const timeAgo = dayDiff === today
? '今天'
: dayDiff === beforeDay
? '1天前'
: dayDiff < beforeMonth
? dayDiff + '天前'
: dayDiff < beforeYear
? Math.floor(dayDiff / 30) + '个月前'
: Math.floor(dayDiff / 365) + '年前'
element.innerHTML = timeAgo
})
最佳实践
在经历两次问题后,我们还是引用第三方库来计算这个时间问题了,而 dayjs
又是目前最流行的库,不仅小而且可以使用的方法也挺多的。
下面是使用的dayjs
的最佳实践,由于这里需要自定义文案,所以需要使用引用其中文语言包和相对事件插件以此实现自定义。
import * as dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import updateLocale from 'dayjs/plugin/updateLocale'
import 'dayjs/locale/zh-cn'
dayjs.extend(relativeTime)
dayjs.extend(updateLocale)
// 覆盖原有的中文时间配置
dayjs.updateLocale('zh-cn', {
relativeTime: {
future: '%s',
past: '%s',
s: '今天',
m: '今天',
mm: '今天',
h: '今天',
hh: function (number) {
/**
* 使用当前时间去计算 number 小时之前的时间(即目标时间)
* -1 是因为 dayjs hour 计算不满 1 小时会按照 1 小时计算
* eg:目标时间:2024-10-18 00:00:00 当前时间是 2024-10-18 14:58 那么这里会计算为15小时之前,则结果为 1 天前
*/
const now = dayjs()
const targetTime = now.subtract(number - 1, 'hours').format('YYYY-MM-DD')
const isSameDay = dayjs(now.format('YYYY-MM-DD')).isSame(targetTime)
return isSameDay ? '今天' : '1 天前'
},
d: '1 天前',
dd: function (number) {
return number >= 7 ? `${Math.floor(number / 7)} 周前` : `${number} 天前`
},
M: '1 月前',
MM: '%d 月前',
y: '1 年前',
yy: '%d 年前'
}
})
dayjs.locale('zh-cn')
export const formatTime = (timeString) => {
return dayjs(parseInt(timeString, 10)).fromNow()
}
总结
这篇文章实现了一个较完善的时间展示功能,避免了手动处理日期复杂性带来的潜在问题。dayjs
库不仅简化了时间处理逻辑,还提供了丰富的功能和插件以满足各种场景需求。希望这篇文章能够帮助到你。