
本文讲解如何在 sequelize 中正确查询 `createddate` 早于当前时间一年(即“一年前及更早”)的数据库记录,纠正常见日期构造错误,并提供可直接运行的安全写法。
在使用 Sequelize 进行时间范围查询时,一个常见误区是误将“一年后”理解为筛选目标——实际上,根据示例数据与预期结果(2022-08-20 被返回),真实需求是:获取创建时间距今已满一年或更久的记录,即 createdDate ≤ 当前时间 - 1年。
你尝试的代码:
[Op.gte]: new Date(new Date().getFullYear(), 1)
存在两个关键问题:
- new Date(year, month) 构造的是 当年 2 月 1 日零点(注意:月份索引从 0 开始,1 表示二月),而非“一年前”;
- 使用 Op.gte(大于等于)会匹配未来时间,与业务目标相反。
✅ 正确做法是:计算一年前的精确时间点,再用 Op.lte(小于等于)筛选:
const { Op } = require('sequelize');
// ✅ 安全计算:当前时间减去一整年(自动处理闰年、月末等边界)
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
return this.findAll({
where: {
createdDate: {
[Op.lte]: oneYearAgo
}
}
});⚠️ 注意事项:
- 不要使用 new Date(Date.now() - 365 * 24 * 60 * 60 * 1000) 简单减毫秒数——它忽略闰秒、夏令时及月份天数差异(如 2023-03-31 减一年应得 2022-03-31,而非错误的 2022-03-30);
- setFullYear() 是最可靠的方式,由 JavaScript 引擎内部处理日期逻辑;
- 若需更高精度(如纳秒级或跨时区一致性),建议在数据库层使用原生函数(如 PostgreSQL 的 NOW() - INTERVAL '1 year'),配合 Sequelize.fn 调用;
- 始终为 createdDate 字段添加数据库索引,以提升时间范围查询性能。
总结:时间查询的核心是语义准确 + 构造安全。牢记“一年前”对应 setFullYear(-1) + Op.lte,即可稳健匹配历史长期留存的数据。










