提问者:小点点

MongoDB和JS之间相同的日期格式,但它们不相等?


当今天的日期(通过Node. js)和日期值(通过MongoDB)相同时,我正在尝试执行操作。但是,我没有收到来自我的for循环的任何输出,表明没有匹配项。

以下是我如何获得今天的日期(日期输出为2023-01-19T00:00:00.000Z):

const d = new Date(new Date().toLocaleString("en-US", { timeZone: "Asia/Hong_Kong" }));
const day = d.getDate();
const month = d.getMonth() + 1;
const year = "2023"; //this is a dummy variable since year is required for Date().
const date = new Date(year + "-" + month + "-" + day);
console.log(date);

这是来自MongoDB的用户文档:

name: "Angelo"
birthday: 2023-01-11T00:00:00.000+00:00 //Date data type

name: "Josh"
birthday: 2023-01-19T00:00:00.000+00:00 //Date data type

这是for循环,当有匹配时应该触发成功,但没有输出。这是我的问题。

let users = [];
db.collection("users").find({})
.forEach((user) => { users.push(user) })
.then(() => {
   for (i = 0; i < users.length; i++) {
      if(users[i].birthday == date) {
         console.log("Success"); //no output on console
      }
   }
})

在控制台中检查用户[i]。生日显示:

  • 2023-01-19T00:00:00.000Z(这不应该是今天的比赛吗?)
  • 2023-01-11 T 00:00:00.000 Z

共3个答案

匿名用户

MongoDB Date对象将值存储在UTC中。在您的示例中,您在本地时区创建了一个日期对象,因此您的日期将不匹配。

您可以使用Date. UTC()静态方法创建一个UTC的零日期,其中零日期表示小时、分钟和秒为零的日期。下面是一个从MongoDB模拟您的用户数组的示例,假设生日都是UTC零日期。您不能直接比较日期对象,因为具有相同日期的两个日期对象具有不同的对象地址。因此,您需要比较日期对象的值(.value eOf()),或字符串表示形式(.toISOString())。

function getUtcZeroDate(str) {
  if(str) {
    return new Date(str + 'T00:00:00.000Z');
  } else {
    let date = new Date();
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  }
}

const users = [
  {name: 'Angelo', birthday: getUtcZeroDate('2023-01-11') },
  {name: 'Josh', birthday: getUtcZeroDate() }, // today
]

const todayUtcZeroDate = getUtcZeroDate();
console.log("Today's UTC zero date:", todayUtcZeroDate.toISOString());

users.forEach(doc => {
  const match = (todayUtcZeroDate.valueOf() == doc.birthday.valueOf()) ? 'match' : 'no match';
  console.log(doc.name + ', born ' + doc.birthday.toISOString(), '=>', match);
});

匿名用户

A simple way to compare dates is to use setHours(0,0,0) for both birthday date and date like below:

const d = new Date(new Date().toLocaleString("en-US", { timeZone: "Asia/Hong_Kong" }));
const day = d.getDate();
const month = d.getMonth() + 1;
const year = "2023"; //this is a dummy variable since year is required for Date().
let date = new Date(year + "-" + month + "-" + day);
date=date.setHours(0,0,0)


for fetching date and comparing from db:
let users = [];
db.collection("users").find({})
.forEach((user) => { users.push(user) })
.then(() => {
   for (i = 0; i < users.length; i++) {
       users[i].birthday=new Date(users[i].birthday).setHours(0,0,0)
      if(users[i].birthday == date) {
         console.log("Success"); // output on console
      }
   }
})

Try it you will get output.

匿名用户

我建议考虑为此使用点. js。您还需要点.timezone.js插件来使用时区。

我推荐点. js,因为有了它,代码变得更具可读性。

moment.tz.setDefault("Asia/Hong_Kong");

const users = [{
    name: "Angelo",
    birthday: new Date('2023-01-11T00:00:00.000+00:00'),
  },
  {
    name: "Josh",
    birthday: new Date('2023-01-19T00:00:00.000+00:00'),
  },
];

const today = moment();

for (i = 0; i < users.length; i++) {
  const user = users[i];
  if ( today.isSame(user.birthday, 'date')) {
    console.log("Success", users[i]);
  }
}
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>