I’m trying to do an action when the date today (via Node.js) and the date value (via MongoDB) is the same. However, I’m not receiving any output from my for loop indicating that there’s no match.
Here’s how I get the date today (date output is 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);
Here’s the users document from 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
Here’s the for loop that should trigger success when there’s a match, but there’s no output. This is my problem.
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
}
}
})
Checking users[i].birthday in console shows:
- 2023-01-19T00:00:00.000Z (Shouldn’t this be a match of today’s date?)
- 2023-01-11T00:00:00.000Z
4
Answers
MongoDB Date objects store values in UTC. In your example you create a date object in the local timezone, so your dates will not match.
You can create a UTC zero date using the
Date.UTC()
static method, where zero date means a date with zero for the hours, minutes, and seconds. Here is an example that simulates yourusers
array from MongoDB, assuming that the birthdays are all UTC zero dates. You can’t compare the date objects directly, because two date objects that have the same date have different object addresses. Therefore you need to compare the value of the date objects (.valueOf()
), or a string representation (.toISOString()
).Output at the time of writing:
I suggest considering using moment.js for this.
You’ll be also need moment-timezone.js add-on to use timezones.
I recommend moment.js because with it, the code becomes more readable.
This is really just a date formatting issue.
If you want to get the date in a particular location, you can use the Intl.DateTimeFormat constructor but get the parts as separate values rather than a timestamp that then must be parsed by the built–in parser. That’s a flawed methodology because the built–in parser isn’t required to correctly parse such input (same with toLocaleString).
So to get the current date in a particular location and then built a timestamp that is 0hrs UTC: