如何将MongoDB多帖子的createdAt转换为“X天前”格式?
批量转换帖子createdAt为“X天前”格式的解决方案
针对时间线场景下的多帖子时间格式化,有两种实用的实现方式:
方法一:后端控制器中批量处理
利用你已有的javascript-time-ago库,在获取帖子列表后遍历每个帖子,生成对应的“X天前”格式字符串并附加到帖子对象上,再传递给EJS渲染。
修改index控制器代码:
const TimeAgo = require('javascript-time-ago'); const en = require('javascript-time-ago/locale/en'); TimeAgo.addDefaultLocale(en) const timeAgo = new TimeAgo('en-US') module.exports.index = async (req, res) => { const posts = await Post.find({}).populate('author'); const currentUser = await User.findById(req.user); // 为每个帖子添加格式化后的时间字段 posts.forEach(post => { post.createdAgo = timeAgo.format(post.createdAt); }); res.render('posts/index', { posts, currentUser, imgLocation }) }
然后在EJS的循环中直接使用这个字段:
<% for (let post of posts){%> <div class="card mb-3"> <div class="row"> <div class="col-md-4"> <% if(post.images.length) { %> <img class="img-fluid" alt="" src="<%= post.images[0].url %>"> <% } else { %> <img class="img-fluid" alt="" src="<%= imgLocation %>"> <% } %> </div> </div> <!-- 添加时间显示 --> <div class="card-footer text-muted"> posted: <%= post.createdAgo %> </div> </div> <% }%>
方法二:前端EJS页面中动态处理
如果希望前端自行处理时间格式化,可以在页面中引入javascript-time-ago的前端版本,遍历帖子时生成时间戳,再通过JS渲染成“X天前”格式。
在EJS页面的<head>中添加库引用:
<script src="https://unpkg.com/javascript-time-ago@2.5.9/bundle/javascript-time-ago.js"></script> <script src="https://unpkg.com/javascript-time-ago@2.5.9/locale/en.js"></script> <script> TimeAgo.addDefaultLocale(en); const timeAgo = new TimeAgo('en-US'); </script>
修改EJS的循环代码,添加时间容器并在页面加载后渲染:
<% for (let post of posts){%> <div class="card mb-3"> <div class="row"> <div class="col-md-4"> <% if(post.images.length) { %> <img class="img-fluid" alt="" src="<%= post.images[0].url %>"> <% } else { %> <img class="img-fluid" alt="" src="<%= imgLocation %>"> <% } %> </div> </div> <div class="card-footer text-muted"> posted: <span class="post-time" data-timestamp="<%= post.createdAt.getTime() %>"></span> </div> </div> <% }%> <script> // 页面加载完成后渲染所有帖子时间 document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.post-time').forEach(el => { const timestamp = parseInt(el.dataset.timestamp); el.textContent = timeAgo.format(new Date(timestamp)); }); }); </script>
两种方法对比
- 后端处理:无需前端额外加载库,页面渲染速度更快,适合静态展示场景;
- 前端处理:若页面停留时间较长,可通过定时任务自动更新时间显示(需额外编写定时逻辑),灵活性更高。
内容的提问来源于stack exchange,提问作者Koki
相关产品推荐
相关产品推荐

