NestJS TypeORM仓储层查询如何比对ISO格式日期与今日日期
解答
基于现有Parsebackenddate函数的实现
你自定义的Parsebackenddate是Node.js运行时的JS函数,无法直接传入SQL查询作用于数据库的schedule.runDateTime字段,可根据场景选择以下两种实现:
- 小数据量场景:查询后在应用层过滤
if (getToday) { const todayDate = dayjs().format('YYYY-MM-DD'); // 先查询满足其他条件的所有记录 const allRecords = await query.getMany(); // 用自定义工具函数过滤出今日数据 const todayRecords = allRecords.filter(item => Parsebackenddate(item.runDateTime) === todayDate ); }
这个方案数据量大时性能极差,不推荐生产环境使用。
- 数据库层面等价转换:把
Parsebackenddate的逻辑替换为对应数据库的内置日期函数,直接在查询时转换字段格式,常见数据库写法如下:- MySQL场景:
if (getToday) { const todayDate = dayjs().format('YYYY-MM-DD'); query.where('DATE_FORMAT(schedule.runDateTime, "%Y-%m-%d") = :todayDate', { todayDate, }); }- PostgreSQL场景:
if (getToday) { const todayDate = dayjs().format('YYYY-MM-DD'); query.where('TO_CHAR(schedule.runDateTime AT TIME ZONE \'UTC\', \'YYYY-MM-DD\') = :todayDate', { todayDate, }); }
更优的替代实现方案
更推荐使用日期范围查询的方案,不需要对字段做函数转换,还可以命中runDateTime字段的索引,性能远高于格式转换比对的方案:
if (getToday) { // 生成今日0点的ISO时间 const todayStart = dayjs().startOf('day').toISOString(); // 生成明日0点的ISO时间 const tomorrowStart = dayjs().add(1, 'day').startOf('day').toISOString(); // 筛选时间落在今日区间的记录 query.where('schedule.runDateTime >= :todayStart AND schedule.runDateTime < :tomorrowStart', { todayStart, tomorrowStart, }); }
这个方案还有两个额外优势:
- 不需要适配不同数据库的日期函数语法,兼容性更强
- 避免时区转换偏差,只要存储的ISO字符串时区统一就不会出现匹配错误
内容的提问来源于stack exchange,提问作者DanDevO
相关产品推荐
相关产品推荐

