如何使用 Sequelize 查询创建时间早于一年前的记录

本文讲解如何在 sequelize 中正确查询 `createddate` 早于当前时间一年(即“一年前及更早”)的数据库记录,纠正常见日期构造错误,并提供可直接运行的安全写法。

在使用 Sequelize 进行时间范围查询时,一个常见误区是误将“一年后”理解为筛选目标——实际上,根据示例数据与预期结果(2025-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) 简单减毫秒数——它忽略闰秒、夏令时及月份天数差异(如 2025-03-31 减一年应得 2025-03-31,而非错误的 2025-03-30);
  • setFullYear() 是最可靠的方式,由 JavaScript 引擎内部处理日期逻辑;
  • 若需更高精度(如纳秒级或跨时区一致性),建议在数据库层使用原生函数(如 PostgreSQL 的 NOW() - INTERVAL '1 year'),配合 Sequelize.fn 调用;
  • 始终为 createdDate 字段添加数据库索引,以提升时间范围查询性能。

总结:时间查询的核心是语义准确 + 构造安全。牢记“一年前”对应 setFullYear(-1) + Op.lte,即可稳健匹配历史长期留存的数据。