Laravel 如何将 MySQL datetime 转换为类似 Facebook 的多久以前格式
实现「多久以前」时间格式的两种常用方案
方案1:在SQL查询层面直接生成(适合快速展示、无需额外业务处理的场景)
以MySQL为例,你可以先自定义时间转换函数,查询的时候直接调用即可:
- 首先创建时间转换函数:
DELIMITER // CREATE FUNCTION time_ago(datetime_val DATETIME) RETURNS VARCHAR(50) DETERMINISTIC BEGIN DECLARE diff INT; DECLARE res VARCHAR(50); SET diff = TIMESTAMPDIFF(SECOND, datetime_val, NOW()); IF diff < 60 THEN SET res = CONCAT(diff, ' 秒前'); ELSEIF diff < 3600 THEN SET res = CONCAT(FLOOR(diff/60), ' 分钟前'); ELSEIF diff < 86400 THEN SET res = CONCAT(FLOOR(diff/3600), ' 小时前'); ELSEIF diff < 2592000 THEN SET res = CONCAT(FLOOR(diff/86400), ' 天前'); ELSEIF diff < 31536000 THEN SET res = CONCAT(FLOOR(diff/2592000), ' 个月前'); ELSE SET res = CONCAT(FLOOR(diff/31536000), ' 年前'); END IF; RETURN res; END // DELIMITER ;
- 调用函数查询posts表即可:
SELECT id, title, content, time_ago(create_time) AS publish_time FROM posts;
注意:如果使用PostgreSQL、SQL Server等其他数据库,只需要修改对应时间差计算函数的语法即可,逻辑完全通用。
方案2:在后端业务代码层面处理(适合多端复用、需要多语言适配的场景)
如果你的业务有国际化需求,或者需要不同端展示规则统一,建议直接从数据库查出原始datetime值,在代码层做转换,以Python为例:
from datetime import datetime def time_ago(dt): now = datetime.now() diff = now - dt if diff.total_seconds() < 60: return f"{int(diff.total_seconds())} 秒前" elif diff.total_seconds() < 3600: return f"{int(diff.total_seconds()//60)} 分钟前" elif diff.total_seconds() < 86400: return f"{int(diff.total_seconds()//3600)} 小时前" elif diff.total_seconds() < 2592000: # 按30天计算 return f"{diff.days} 天前" elif diff.total_seconds() < 31536000: # 按365天计算 return f"{int(diff.days//30)} 个月前" else: return f"{int(diff.days//365)} 年前"
你可以根据自己的技术栈(Java、Go、Node.js等)改写上述逻辑,也可以调整时间分界值适配你想要的展示效果,比如超过7天就展示原始日期而非「X天前」。
内容的提问来源于stack exchange,提问作者Mohamed Essam
相关产品推荐
相关产品推荐

