一、页面显示异常
该bug源于一个简单的报表展示需求,在日期选择框中默认显示两天前的日期。我看了看同事留下的代码,觉得挺简单,直接进行复用:
java
function curDt() : void {
var date : Date = new Date();
var y : number = date.getFullYear();
var m : number = date.getMonth()+1;
var d : number = date.getDate() - 2; // 就是这里!
var startT : string = y+"-"+(m<10?('0'+m):m)+"-"+(d<10?('0'+d):d);
}
需求上线半个月都没有出现什么问题,直到12月1号,业务反馈前端日期展示变成了:
2025-12-0-1
一看才发现,不止我这一个地方出错了,其余采用这种计算逻辑的页面日期也全乱了。
二、错误分析
假设今天是 2025年12月1日,那么date.getDate() = 1,date.getDate() - 2 = -1,而三元运算符处理负数 (d < 10 ? ('0' + d) : d) ,-1 < 10 成立,所以结果是 '0' + (-1) = '0-1',最后再拼接年月就变成了2025-12-0-1。
三、修复方案
使用js内置函数,setDate() 方法,Date对象会自动处理跨月、跨年的边界情况,先date - 2, 再计算年、月、日。
java
// 获取两天前的正确日期
const date = new Date();
date.setDate(date.getDate() - 2); // 自动处理跨月跨年
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
// 格式化日期
const format = (num: number) => num < 10 ? '0' + num : num;
const startT = `${y}-${format(m)}-${format(d)}`;
其实这也是一种值得注意的编码规范,就是涉及时间计算的时候,能尽量使用内置函数就使用内置函数,自定义时间计算函数容易带来跨年和跨月问题。