The issue at a high level:
A hotel owner sets a time range as to when a reservation can be booked at a restaurant (5pm – 10pm). In this record, there will also be a timezone, so when the data gets displayed to a user, I can convert the date to the original timezone it was encoded in. This is so a user in another timezone can see the dates as they were intended and not encoded into their local timezone.
The issue:
If a user is in another timezone, making a reservation, their data will be stored as so:
date: DateObj
timezone: zyx
If I am now trying to retrieve all the reservations for the day, I am foreshadowing an issue:
- If the UTC timestamp is less the previous / next day it will not be found
here is a snippet of the grabbing method
const startOfDay = new Date(dateParam);
startOfDay.setHours(0, 0, 0, 0);
const startOfNextDay = new Date(startOfDay);
startOfNextDay.setDate(startOfDay.getDate() + 1);
const reservations = await this.reservationModel
.find({
reservationDate: {
$gte: startOfDay,
$lt: startOfNextDay,
},
restaurantId: restaurantId,
})
Potential solution:
I could pass the date as a broken up string
{
day: 12,
month:11,
year:2024,
time:xyz
}
and construct the date using the servers timezone so it will always be consistent. So when I am getting the reservations, there will be no time zoning issues since all dates will be in the servers timezone.
I was curious to know if I could set the startOfDay date variable to use the start of the UTC day. Would this be something that would work as well?
2
Answers
Setting the startOfDay variable to the start of the UTC day can indeed be an option to avoid timezone issues. This will ensure consistency in how dates are handled regardless of the user’s timezone.
You can achieve this by using methods like setUTCHours, setUTCMinutes, and setUTCSeconds to set the time components to zero in the UTC timezone. Something like this should theoritically work,
I don’t agree with @Matt Johnson-Pint. A Date is a Date and
Date
Objects in MongoDB / JavaScript are stored as UTC time, this you cannot change. But actually you should not care about the internal storage format of aDate
object. For example, in OracleDATE
are stored as internal binary value, there you don’t care either.Storing Date/Time values as string is a design flaw, you should never do that. This is not limited to MongoDB, it applies to any database. Here on SO you can find hundreds of question where people run into problems because they store date values wrongly as string.
Now, having said all this, regarding to your question: In general, when people have to work with times and timezones I recommend to use a 3rd party Date library, e.g. Luxon, Day.js or (deprecated) moment. They are much easier to use.
In your case the solution could be this one:
If you like to get all reservations from a specific day, it could be
All your times are in New York time zone, thus you can also use it as default:
will do the same.