统一博客的时间格式
上一篇文章提到 day.js
这个库,并使用 dayjs/plugin/relativeTime
这个插件来实现几分钟前、几小时前、几天前这样的相对时间格式。
想使用相对时间格式是因为现在使用的 Artalk 评论,为了与之匹配,就想将博客显示时间的格式换成动态的相对时间。可当时没有观察仔细,后来回复空白评论时才注意到,原来 Artalk 评论的相对时间是有条件控制的。
搜索 Artalk 官方文档,看到一个配置项 dateFormatter
时间格式化函数发现超过 7 天就会显示具体日期,使用文档上的方法,的确可以使用 day.js
来进行配置。可当我查看 Artalk 源码时又有了新的想法,想要统一时间格式,好像也可以舍弃 day.js
直接使用 Artalk 的方案。
一、创建工具函数
// src/utils/relativeTime.ts
// 引用 Artalk 源码
// https://github.com/ArtalkJS/Artalk/blob/99736db27fab1d260423dc6d48f82778adb8c235/ui/artalk/src/lib/utils.ts#L61-L108
export function padWithZeros(vNumber: number, width: number) {
let numAsString = vNumber.toString();
while (numAsString.length < width) {
numAsString = `0${numAsString}`;
}
return numAsString;
}
export function dateFormat(date: Date) {
const vDay = padWithZeros(date.getDate(), 2);
const vMonth = padWithZeros(date.getMonth() + 1, 2);
const vYear = padWithZeros(date.getFullYear(), 2);
return `${vYear}-${vMonth}-${vDay}`;
}
// 自定义 timeAgo,后续也可用回到 Artalk 上。
export function customTimeAgo(date: Date) {
try {
const oldTime = date.getTime();
const currTime = new Date().getTime();
const diffValue = currTime - oldTime;
const days = Math.floor(diffValue / (24 * 3600 * 1000));
if (days === 0) {
const leave1 = diffValue % (24 * 3600 * 1000);
const hours = Math.floor(leave1 / (3600 * 1000));
if (hours === 0) {
const leave2 = leave1 % (3600 * 1000);
const minutes = Math.floor(leave2 / (60 * 1000));
if (minutes === 0) {
const leave3 = leave2 % (60 * 1000);
const seconds = Math.round(leave3 / 1000);
if (seconds < 10) return '刚刚';
return `${seconds} 秒前`;
}
return `${minutes} 分钟前`;
}
return `${hours} 小时前`;
}
if (days < 0) return '刚刚';
if (days < 8) {
return `${days} 天前`;
}
return dateFormat(date);
} catch (error) {
console.error(error);
return ' - ';
}
}
// 更新相对时间函数
export const updateRelativeTimes = () => {
const relativeTimeElements = document.querySelectorAll('.relative-time');
const updateTime = () => {
relativeTimeElements.forEach((element) => {
const publishDate = element.getAttribute('data-publish-date');
if (publishDate) {
const publishDateObj = new Date(publishDate);
element.textContent = customTimeAgo(publishDateObj);
}
});
};
setInterval(updateTime, 60000);
updateTime();
};
二、接收工具函数
简单举例:
<p class="relative-time text-sm text-gray-600 dark:text-gray-400" data-publish-date={post.data.publishDate}>
{post.data.publishDate}
</p>
<script>
// 导入工具函数
import { updateRelativeTimes } from '../utils/relativeTime';
document.addEventListener('astro:page-load', () => {
updateRelativeTimes();
});
</script>
如此一来就将 Artalk 上的动态相对时间应用在博客上了,又进一步地压缩了 Astro 的打包体积,少了差不多 4 KB,哈哈哈。
三、扩展
- 如果感觉超过 7 天显示具体时间这个条件太短的话,可修改
if (days < 8) {
return `${days} 天前`;
}
// 简单举例
if (days < 60) {
return days < 28 ? `${days} 天前` : '1 月前';
}
- 将工具函数中的
customTimeAgo
应用回 Artalk
import { customTimeAgo } from '../utils/relativeTime';
Artalk.init({
// ... 其他配置
dateFormatter: (date) => customTimeAgo(new Date(date)),
})
这样的话修改 customTimeAgo
的逻辑也能应用到 Artalk 中。