设置订单日期为午夜及Ticks赋值问题技术咨询
修正MongoDB日期处理脚本的两个问题
你在调整MongoDB订单的OrderDate字段时遇到了两个棘手的问题,我来帮你逐一解决:
问题1:日期变为05/04/2020而非17/04/2020 00:00:00的原因及修复
错误根源
你代码里调用的getDay()方法坑了你——这个方法返回的是星期几(0=周日,1=周一,…,6=周六),而不是当月的具体日期。2020年4月17日是周五,getDay()返回5,所以新构造的Date对象把日部分设成了5,最终就变成了05/04/2020。
修复代码
把getDay()换成getDate(),这个方法才会返回当月的日期(1-31)。修正后的日期构造代码如下:
order.OrderDate.DateTime = new Date( order.OrderDate.DateTime.getFullYear(), order.OrderDate.DateTime.getMonth(), order.OrderDate.DateTime.getDate(), // 替换为getDate() 0, 0, 0, 0);
运行后就能得到你期望的17/04/2020, 00:00:00了。
问题2:设置Ticks时出现"Cannot set property 'Ticks' of null"错误的解决
错误原因
这个报错说明执行order.OrderDate.Ticks = ...时,order.OrderDate是null。大概率是部分订单文档的OrderDate字段本身就不存在,或者在遍历过程中遇到了异常文档。另外你之前用固定的Ticks值也是错误的——636475104000000000是2017-11-29的Ticks,不能复用在其他日期上。
完整修复方案
先添加字段存在性判断,再根据修正后的日期计算正确的Ticks值:
function (order) { // 先检查OrderDate是否存在,避免null错误 if (!order.OrderDate) { print(`跳过订单 ${order._id}:不存在OrderDate字段`); return; } const originalDate = order.OrderDate.DateTime; // 构造当天0点的日期 const correctedDate = new Date( originalDate.getFullYear(), originalDate.getMonth(), originalDate.getDate(), 0, 0, 0, 0); print("原始时间 = " , originalDate.toLocaleString()); print("修正后时间 = " , correctedDate.toLocaleString()); order.OrderDate.DateTime = correctedDate; // 计算对应Ticks:MongoDB的Ticks是从0001-01-01开始的100纳秒数 const msSinceEpoch = correctedDate.getTime(); // 1毫秒=10000Ticks,加上1970-01-01之前的基准Ticks(621355968000000000) const correctTicks = NumberLong(msSinceEpoch * 10000 + 621355968000000000); order.OrderDate.Ticks = correctTicks; db.Orders.save(order); }
这个方案既避免了null报错,又能为每个日期生成匹配的正确Ticks值,不会再出现用旧日期Ticks的问题。
内容的提问来源于stack exchange,提问作者CipherShark
相关产品推荐
相关产品推荐

