Using ISODate with mongodb query and node.js - javascript

I am creating a string -
queryString - {"Project": "Serenity","DateOfWalkin": {"$gte": "2022-03-01" ,"$lt": "2022-03-31"} }
then parsing it - queryObject = JSON.parse( queryString )
It is parsing successfully, but when I run the query it does not give me any result.
Now when I update the same query by using ISODate for both dates, and then tried running the query in Mongo compass, it works fine.
I want to use ISODate() but the problem is the way I am building the queryString is based on different conditions from the user input, now if a particular condition is true then and only then I want to query that particular field. For other fields I am searching, which are of type "String" in my db, I am able to get the correct result, but for date I am facing this issue.
startDate and endDate are user inputs using date picker in HTML
TRIAL number 1
queryString = queryString + ,"DateOfWalkin": {"$gte": ISODate("${startDate}")} ,"$lt": { "$date" : ISODate("${endDate}") } }
This will give a parser error saying identifier "I" not found, hence I am not able to parse this string.
To combat this, I tried to use new Date object, tried to convert the date using toISOString, but it didn't work.
TRIAL number 2
queryString = queryString + ,"DateOfWalkin": {"$gte": "ISODate("${startDate}")"} ,"$lt": { "$date" : "ISODate("${startDate}")" } }
If we use double quotes for ISODate as well, it will solve the parser issue but Mongo query will not give any result and it is treating ISODate wrapper as a string literal.
TRIAL number 3
queryString = queryString + ,"DateOfWalkin": {"$gte": "${startDate}"} ,"$lt": { "$date" : "${endDate}" } }
Does not give result
TRIAL number 4
Using new Date() to get the ISODate format
Query becomes -
{
Project: 'Serenity',
DateOfWalkin: {
'$gte': 'Tue Mar 01 2022 05:30:00 GMT+0530 (India Standard Time)',
'$lt': 'Thu Mar 31 2022 05:30:00 GMT+0530 (India Standard Time)'
}
}
Still it doesn't give any result
TRIAL number 5
Query object -
{
Project: 'Serenity',
DateOfWalkin: {
'$gte': { '$date': '2022-03-01' },
'$lt': { '$date': '2022-03-01' }
}
}
Above doesn't give result
Is there any way I can store the value of ISODate("${startDate}") and use that variable in the main queryString?
Or is there a better way to compare dates when I am using the input dates as user input?
I have tried multiple approaches and kinda feeling stuck at this point.

Why do you parse the string?
Apart from your current problem, you also open the door for NoSQL-Injection. You can compose the query object also directly like this:
const queryObject = {};
queryObject["Project"] = "Serenity";
queryObject["DateOfWalkin"] = { $gte: ISODate("2022-03-01"), ["$lt"]: ISODate("2022-03-31") };
const ninDates = [];
ninDates.push(ISODate("2022-03-10"));
ninDates.push(ISODate("2022-03-20"));
queryObject["DateOfWalkin"]["$nin"] = ninDates;
db.collection.find(queryObject)
If you really insist to parse the string, then use ejson
EJSON.parse('{ "Project": "Serenity", "DateOfWalkin": { "$gte": { "$date": "2022-03-01" }, "$lt": { "$date": "2022-03-01" } } }')
Should give desired queryObject. Note, keys and values need to be enclosed by double-quotes (")

Related

explain MongoDB date format

For defining a model in node.js I am using mongoose library and I want to store the date in that.
here is the schema:
availability: [
{
day: {
type: String,
},
startTime: {
type: Date,
},
endTime: {
type: Date,
},
},
]
I am passing the value from postman like below:
{
"parkingId":"62cfa09adb8bc68f045b4d65",
"day":"Monday",
"startTime":7,
"endTime": 22
}
But it is getting saved like this from 1970. I am aware that passing a time like this will calculate time from Unix epoch But I want to save today's date or date passed by merchant user for availability
day:Monday,
startTime: ISODate("1970-01-01T00:00:00.007+00:00"),
endTime: ISODate("1970-01-01T00:00:00.022+00:00")
And also what is 007+00:00 or 022+00:00?
Should I use moment library for that?
This is unrelated to MongoDB, this is a mongoose feature.
You define startTime and endTime as Date in your schema, but you are passing a number. let's see what the mongoose code does in this scenraio:
function castDate(value) {
...
let date;
if (value instanceof Number || typeof value === 'number') {
date = new Date(value);
}
...
};
As you can see in the case the input value is a number which is the case here, the mongoose schema casts this value to date using js new Date() function which is basically:
JavaScript Date objects represent a single moment in time in a platform-independent format. Date objects contain a Number that represents milliseconds since 1 January 1970 UTC.
This means when it casts new Date(7) the result is 1 January 1970 UTC + 7 mili seconds whichi is the 7 your seeing in the result 1970-01-01T00:00:00.007+00:00
Clearly in your case all you need to do is change the Date type to Number which is actually what you're trying to save.

checking the ISO data format is not working

I'm trying to check if the 'date-time' string is ISO formatted and I get the following output:
isIsoDate the date string is not ISO format! : 2022-04-21T09:40:01.000Z
isIsoDate converted-back date : 2022-04-21T09:40:01.000Z
isIsoDate time stamp number : 1650534001000
isIsoDate string builded back : Thu Apr 21 2022 11:40:01 GMT+0200 (Ora legale dell’Europa centrale)
this is my code:
export function isIsoDate(dateString) {
var dateParsedNum = Date.parse(dateString);
var dateBackToString = new Date(dateParsedNum);
var stringBuilded = "";
stringBuilded = dateBackToString.toString()
if ((dateBackToString.toString()) == dateString) {
return true;
} else {
console.debug("isIsoDate() the date string is not ISO format! : ", dateString);
console.debug("isIsoDate() converted-back date : ", dateBackToString);
console.debug("isIsoDate() time stamp number : ", dateParsedNum);
console.debug("isIsoDate() string builded back : ", stringBuilded);
// throw new BadRequestException('Validation failed');
}
return(false)
}
I'm not sure if it can be done with JavaScript's Date utilities. As Salman said in the comments, you can have .toISOString() instead, but this method converts everything into UTC, whereas the ISO specification is more flexible than that.
I recommend this StackOverFlow answer that uses RegEx to validate ISO strings.
did you check the setting?
there is several solutions in the site

How to create date object from string retrieved from JSON?

I would like to create a new Javascript date object and save it to a variable all from a JSON endpoint route. The JSON looks like this:
[
{
"class_instructor": 1,
"id": 1,
"location": "Boise",
"start_date_time": "Thu, 19 Nov 2020 09:10:00 GMT"
},
{
"class_instructor": 1,
"id": 2,
"location": "Meridian",
"start_date_time": "Mon, 16 Nov 2020 09:10:00 GMT"
}
]
I have been able to grab each objects value through iteration using Axios and saving it to a variable, however I would like to generate a javascript date object from the start_date_time value's strings. I am sure I can grab each of character of the string and eventually create the date object by individually adding each year, month, day... let this_date = new Date(2020, 11, 19, 9, 10)
However, this doesn't appear to be fullproof and there has got to be an easier way.
use this to create new date from your string
var getDateFrom = array[0].start_date_time;
var setDateTo = new Date(getDateFrom);
//this sets date using string format like you have
it is simple you need just to call Date with your string.
const a= new Date('Thu, 19 Nov 2020 09:10:00 GMT')
or in general :
const a= new Date('start_date_time')
you can verify that in console, when you click . after a a.
the properties and functions of the Date type will appear.

Saving a String in MongoDB as a date saves wrong values

I am trying to save a string in MongoDB as a date but having hard times for storing the right values.
In Mongoose schema data value is stored as Date, however, I pass the value to data as new Date("MM-dd-YYYY") but when I look up in the database the value is transformed to this format ISODate("YYYY-MM-dd-1T21:00:00Z")
The format wouldn't bother me if the date would be the same but as you notice the value in the database is one day earlier then the value which I want to be.
So instead of 2018-09-20 is 2018-08-19. My guess is that default UTC time is not the same or something like that but how can I set the correct UTC time?
Edit:
var mongoose = require('mongoose')
var dateformat =require('moment');
//Schema
var ReservationSchema = mongoose.Schema({
name : {
type:String,
required : true,
},
numberOfGuests : {
type : Number ,
required : true,}
,
email: {
type : String,
required:true,
},
phone: {
type : String,
required:true,
},
data:{
type:Date,
require:true,
},
timetables:{
type:String,
require:true,
},
furtherRequests: {
type : String,
}
});
var reservvar = module.exports = mongoose.model('Rezervari', ReservationSchema ,'Rezervari');
module.exports.createReservation = function (query,callback){
//query.data = dateformat.utc(query.data).format("MM-DD-YYYY")
reservvar.create(query,callback);
}
module.exports.getReservations = function (callback){
reservvar.find({},callback);
}
Index.js file :
app.get('/api/reservations',function(req,res) {
Rezervari.getReservations(function(err,reserv){
if(err){
throw err;
}
var changetime = reserv[1].data;
console.log(reserv[1].data)
changetime = dateformat.utc(changetime).format("MM-DD-YYYY") // this one returns the date in desired format but with wrong values as stored in db
console.log(changetime)
res.json(reserv);
});
});
app.post('/api/createrezervare', function (req,res) {
const reserv = req.body
const name = reserv.name
const numberofg = reserv.number
const phone = reserv.phone
const email = reserv.email
const data = reserv.date
const timetable = reserv.time
const furtreq = reserv.frequests
Rezervari.createReservation({name:name,numberOfGuests:numberofg,phone:phone,email:email,data:data,timetables:timetable,furtRequests:furtreq},function(err,reserv){
if(err){
throw err}
res.json({status:true})
})
})
You are inserting a Javascript Date Object from Node.js, and that same Date is being inserted in MongoDB, it's being inserted correctly.
I think you are confusing how dates are stored internally and how are they formatted when you print them.
When you check the content of your data in MongoDB it's just shown in that particular format, an ISO date. If you take a close look at the date shown you can see a Z a the end, Z means "zero hour offset" also known as "Zulu time" (UTC).
In Javascript when you create a Date object without setting the timezone, it's by default created in your system timezone. Also, Date objects are not stored with any format, nor in JS nor in MongoDB. In JS, dates are stored internally as time values (milliseconds since 1970-01-01).
Supposing we are in Japan, JST time (UTC+9):
const d = new Date("09-20-2018");
console.log(d.getTime()); // 1537369200000
console.log(d.toString()); // Thu Sep 20 2018 00:00:00 GMT+0900 (JST)
console.log(d.toISOString()); // 2018-09-19T15:00:00.000Z
First we are printing out the number of ms, after the Date including the timezone, and finally the ISO Date, almost same format that MongoDB uses to print dates in the Mongo shell (anyway, in UTC).
So, new Date("09-20-2018") is going to store the milliseconds until 09-20-2018 00:00 in Japan Time. Then, if you insert that object in MongoDB, internally it will store the correct date (I don't know internal details of MongoDB, but maybe it's storing the milliseconds as well).
If you check MongoDB you will see something like ISODate("2018-09-19T15:00:00Z").

how can change the text string to date object?

i am getting string from server and i need to covert that fetching string in to new date object.. for doing this, i tried this function, but no use, any one can help me to convert strings to date object?
my code is :
var nationZone = {
getNewYorkLocalTime : 'getTime.php?lat=40.71417&lan=74.00639',
getLondonLocalTime : 'getTime.php?lat=51.5&lan=0.1166667',
getChennaiLocalTime : 'getTime.php?lat=13.0833333&lan=80.2833333',
getBangaloreLocalTime:'getTime.php?lat=12.9833333&lan=77.5833333'
}
$.each(nationZone , function(key, value){
$.get(value, function(response){
var newdate = $(response).find('localtime').text();
if(key == "getNewYorkLocalTime"){
var newyourktime = new Date(newdate);
newyourktime.getTime()
}
});
});
but, the newyourktime is showing local time only.. any help please? as well i am getting the response from server is : 17 Nov 2011 18:09:47 - like this.
Use http://www.datejs.com/
As an example:
var newyourktime = Date.parse('2011-11-11, 11:11 AM');
alert(newyourktime.toString('dd/mm/yyyy HH:mm:ss EST'));
Check out the Datejs library documentation to meet your requirements, after your date string is parsed, you can do a lot with it.
This will try to parse the date using the client machine own local settings, which is not good.
Instead of passing it as string, pass it as the total seconds that passed since 1/1/1970 at midnight and use this number when constructing the new Date object of JavaScript.
For example pass this number: 1321614000000 and you will get November 18th 2011, 1 PM
You could use substr
day = newdate.substr(0,2);
month = newdate.substr(3,3);
year = newdate.substr(7,4);
var newyorktime = new Date(year, month, day);
Substr

Categories