最省事的是直接用 layui.util.toDateString,但字段名必须与后端 JSON key 完全一致,否则自动 fallback 到当前时间;支持秒级/毫秒级时间戳,格式仅认 yyyy-MM-dd HH:mm:ss,空值返回空字符串,推荐函数式 templet 显式兜底。

直接用 layui.util.toDateString 最省事,但字段名必须和后端返回的 JSON key 完全一致,否则它会悄悄替换成当前时间——这不是 bug,是设计行为。
templet 里调用 layui.util.toDateString 的正确写法
必须确保三点:函数名拼写准确、第一个参数是真实字段名、第二个参数是合法格式字符串。Layui 2.x 和 3.x 都支持这个 API,无需额外加载模块。
-
templet: '<div>{{layui.util.toDateString(d.create_time, "yyyy-MM-dd HH:mm:ss")}}</div>'—— 字段名是create_time,不是createTime或created_at - 如果后端返回的是秒级时间戳(10 位),
toDateString会自动乘 1000;毫秒级(13 位)也兼容,不用手动处理 - 格式字符串不支持大写
YYYY或小写hh,只认yyyy、MM、dd、HH(24 小时)、mm、ss - 字段为空(
null/undefined/"")时,toDateString会返回空字符串,不会报错,但显示可能突兀,建议加兜底
字段为空时怎么避免显示“Invalid Date”或空白
虽然 toDateString 对空值较友好,但某些旧版 Layui 或自定义封装下仍可能出问题。稳妥做法是显式判断:
- 用函数式
templet替代字符串模板:templet: d => d.create_time ? layui.util.toDateString(d.create_time, 'yyyy-MM-dd') : '-' - 别写成
{{# if(d.create_time){ }}...{{# } else { }}-{{# } }}这种模板语法——Layui 2.x 不解析#块,只会原样输出 - 如果字段是字符串日期(如
"2026-09-04"),toDateString也能识别,但不推荐依赖;后端统一发时间戳更可控
为什么写了 toDateString 却总显示今天的时间
90% 是字段名不匹配。Layui 内部逻辑是:当 d.xxx 取不到有效值时,就 fallback 到 new Date()。打开浏览器控制台,console.log(d) 看一眼真实结构,比猜快十倍。
- 后端返回
{"sbj_start": 1725458700000},你就得写d.sbj_start,写d.startTime就失效 - 字段名含大小写、下划线、驼峰,必须一字不差。JSON 是
pressTime,JS 对象里就是d.pressTime,不是d.presseTime - 如果用了
parseData重映射过数据,要以重映射后的字段名为准,不是原始接口字段
复杂格式(如“今天”“昨天”“2天前”)要不要用 laydate.format
不要。这个方法不是所有 Layui 版本都内置,v2.8+ 才稳定;且它本质只是字符串格式化工具,跟 toDateString 功能重叠,还多一层模块依赖风险。
- 相对时间需要自己写逻辑,比如:
const diff = Math.floor((Date.now() - d.create_time * 1000) / (1000 * 60 * 60 * 24)) - 用函数式
templet更灵活:templet: d => { const days = ...; return days === 0 ? '今天' : days === 1 ? '昨天' : `${days}天前`; } - 注意:时间戳单位要统一,后端秒级就
* 1000,毫秒级直接用;别混着来
最易被忽略的一点:表格列配置里的 field 值和 templet 里写的 d.xxx 必须是同一套命名体系,中间任何一层(接口响应、parseData、done 回调)改了名,这里就得同步改——漏掉一个下划线,就白调一晚上。


















