MERN - Query fetching previous dates values from DB while doing date filter - node.js

MongoDB:
I have a table in mongo with timestamps attribute set. The following dates are automatically created by the DB while saving the documents.

Request:
Now when i am querying for the documents form the UI, the request values are like follows (date)

Backend Logic:
if (filters.date) {
startDate = new Date(filters.date);
startDate.setHours(0, 0, 0, 0);
endDate = new Date(filters.date);
endDate.setDate(endDate.getDate() + 1);
endDate.setHours(0, 0, 0, 0);
}
datePredicate = {'createdAt': {"$gte": startDate, "$lt": endDate}};
Response:
The response received ( notice the the date is one day old )

In UI:
Here also it shows one day old date from the record fetched. Indeed the query fetches the objects saved on the previous day.

Kindly let me know why I am not getting the records for the chosen date, but one day before.
Note:
However this logic works perfectly in my localhost, just not in the prod instance.
Also when i pass the request as below, it works as expected.

What am i missing? I am confused with formatting dates. Kindly suggest.

If you have a server which is not located at the same timezone you are hitting from, then you'll run into this issue, this is especially true if you are using string to communicate in between. That is also the reason why you don't see this in your localhost.
When you save the date in the database, if you are using a string, then you need to make sure it's timezone immune, which means you have to choose A) certain string format, "Z" or B) date format if it carries with the timezone. Basically you have to make sure what you stored in the database can be safely converted back to any time format in the future, ex. your browser timezone.
Simply put, "6/27/2020" is very misleading, it could mean anything. But if you are using UTC time format (ex. "Z"), then you know this date has been uniquely locked to a particular timezone. Even if you switch timezone, you'll find ways to convert in between. The base reference timezone does matter here.
Hope this helps, sorry I didn't show you any code, but this is more like a understanding question than coding problem.

Related

Node application and insertion in Mongodb timestamp, problem with Date type and locale time

I have a node application that receives data from MQTT, where various parameters and timestamp are sent to the broker. The server and hardware are correctly configured with local time (Spain).
When I am going to do the insertion in the database, in this case MongoDB, I format the timestamp to be able to insert it in the mongo date format.
The problem is that only the javascript Date() can insert the date format in mongo and I always get two hours less than my local time.
//Format timestamp to date with dayjs
let date = dayjs(data.channels.timestamp * 1000).format()
//Output: 2021-09-16T13:32:33+02:00
//Format date to insert in MongoDB
let timestamp_ = new Date(date);
//Output: 2021-09-16T11:32:33.000Z
The correct date is: 2021-09-16T13:32:33+02:00
I tried momentjs and I have the same problem.
It is normal to have date in timezone GMT+0. Date object assumes the date is always GMT+0. Keep it like that and store everything in GMT+0.
Manipulate your query according to the time zone, not the data stored.

What does Google Big Query expects in date column?

I'm sending a JSON with some data to Google Big Query, all string and numeric columns are accepting my data just fine, however, whenever I try to send a data to the Date column it returns a error saying:
'invalid',
location: 'creationdate',
debugInfo: '',
message: "Invalid date: '2020-10-05T00:00:00.000Z'"
I'm using Node.js to work with the data and sending it to Google Big Query through the insertAll route, following the format told by them on their docs: https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/insertAll
If I send the data as Null it works fine, I've also tried to send it as a string and as an integer, but it returns the same error.
To confirm is the data type on the BigQuery schema Date or Datetime?
You may need to truncate to fit the date format or switch to using datetime.
For some reason the Date format in Big Query only accepts YYYY-MM-DD, without hours or timezone, I had to create another column in my table so I would be able to store the hours and timezone.

mongodb date conversion is weird

I'm making a small employee management system in which I have to play with dates in many places like attendance, leaves etc.
I use luxon for dates in my node.js project. Ex: DateTime.fromISO("2020-10-15"); gives me this in the console: 2020-10-15T00:00:00.000+05:00
but when I save it in mongodb it becomes 2020-10-14T19:00:00.000+00:00 and this is problematic because i need to query objects to check if there is an attendance marked in the same day or to get today's attendance. How can I solve this issue?
Storage
When MongoDB stores time-type data, it is first converted to UTC time and then stored in the database. The date submitted by the client is East 5, and the conversion to UTC time is minus 5 hours;
Read
MongoDB will convert the UTC date stored in the database into the East 5 zone of the client according to the time zone of the client, and then return it to the client
MongoDB only has a timestamp type, it does not have a date type. Dates are converted to times when they are stored. Which timezone the date is interpreted to be in can vary, looks like your driver uses the beginning of specified date in UTC. Ruby works the same way and you can read more about the principle here.
To "solve this issue", either only store and query by timestamps in MongoDB, converting dates to timestamps in your application, or understand how your language and driver converts dates to timestamps (note that JS Date type is actually a timestamp).

MongoDB/Mongoose timezone date decrement problem

I've got an edit page with a "date" type input. I'm using node.js, express, and mongoose to pull the content of the input and save it to the database using a date field in a Mongoose model. When I log the date before it goes into the database I'm seeing:2020-03-31. When I look at it in the database I'm seeing:2020-03-31T00:00:00.000+00:00. Does that +00:00 mean it's getting a timezone assigned? Do I need to edit how my MongoDB database is storing dates?
I'm running into trouble with the time zone when I read it back out and use it to populate the input on the edit page. I'm using a Mongoose model function to format the date before it goes into the value field on the html input. Within that function I'm running the below code:
console.log(date);
// Output:
// 2020-03-31T00:00:00.000Z
console.log(date.getDate());
// Output:
// 30
Is the 'Z' coming from the "+00:00" above? I'm GMT-4, so my server is interpreting that time as March 30th at 8pm and now the date picker on the edit page is populated with March 30th instead of the 31st. If I save this, then the next time I load the page the input will read March 29th. I don't want to unintentionally decrement the date by one every time the page is loaded and saved!
In this case, I really don't care about time and just want to refer to the date. Is there a different best practice I can use here?
MongoDB stores timestamps only, it does not have a facility to store dates. Javascript similarly does not have a facility for storing dates natively contrary to what you might expect - the Date type is actually a DateTime. Mongoose also does not have a date type (it uses JS Date which is a datetime).
What this means is:
When you are converting user input to a JS Date instance, you are getting the date converted to a datetime (sounds like the time component is zero in UTC in your application).
When you are reading the date out of the database, you are reading a datetime (which is the beginning of the day of that date in UTC per your provided information, not in your local time).
I would then proceed as follows:
The DateTime you are reading is the beginning of day on your date in UTC.
If mongoose converts the time to your local time, as it appears to do, you need to either stop it from doing that or convert back to UTC.
Then retrieve the year-month-day components of the UTC datetime.
Using these components you can create a new Date instance in local time or do whatever else you wish such as rendering them.
There are various libraries available in JS for dealing with dates and time zones, but the language itself has limited date support.

Moment date format changing from Node to MongoDB

I am creating an app in node js and saving date to Mongo DB, the datatype of Mongoose, I used to save is Date.
moment.locale("pt");
today= moment().startOf("day").format();
The date is printing like 2019-05-27T00:00:00-03:00
But when it is saving and I am trying to retrieve the date it is coming from mongo db like 2019-05-27T03:00:00.000Z
Now the comparison didn't work. So I am finding data based on this date and it is not working.
I am using locale for Brazil.I am keeping the user details day wise from 00:00 to next 24 hours and doing a luck draw of users. So I have huge database and want to filter data based on today date. So I need date should be saved in local timezone i.e. Brazil.
Any help would be appreciated.
I suggest moving to UTC, then changing the locale, then mutating the date to match the day's beginning and then storing as ms:
const d = moment
.utc() // Get the UTC time
.locale('pt_BR') // Change locale to Brazil
.startOf('day') // Go back in time to current date # 00:00:00
.valueOf() // Get ms value
// store d in the database

Resources