Mongoose: Cast to date failed for value when updating a document - javascript

I use Mongoose in my project and in one of the schemas I use Date field, like this:
reservationDay: {
type: Date,
default: Date.now
}
I can create document with this field without a problem. And when I console.log this date after it has been created I get:
reservationDay: Thu Nov 20 2014 04:45:00 GMT+0100 (CET)
However, there is a problem when I try tu update this document (even without changing reservationDay field). Here is the error message I get:
name: 'CastError',
message: 'Cast to date failed for value "20/11/2014 04:11" at path "reservationDay"' } CastError: Cast to date failed for value "20/11/2014 04:11" at path "reservationDay"
Here is how I update this document on server side:
Reservation.findOne({ _id: id }).exec(function(err, reservation) {
if (err) {
//handle
}
if (!reservation) {
//handle
}
reservation = extend(reservation, req.body);
reservation.save(function(err, updatedReservation) {
if (err) {
//handle
}
return res.json(reservation);
});
});
and the date is not changed in the req.body.
Any ideas what might cause this error?
Thanks!

"20/11/2014 04:11" is an invalid ISODate format. Somewhere you are converting reservationDate into a string of an invalid format. You need to convert it to a valid ISODate format (month before day):
new Date("11/20/2014 04:11") // Thu Nov 20 2014 04:11:00 GMT+0100 (CET)
new Date("2014/11/20 04:11") // Thu Nov 20 2014 04:11:00 GMT+0100 (CET)
new Date("20/11/2014 04:11") // Invalid Date
for easy manipulation of date formats, I'd recommend using moment.js

Convert date to MongoDB ISODate format in JavaScript using Moment JS
MongoDB uses ISODate as their primary date type. If you want to insert a date object into a MongoDB collection, you can use the Date() shell method.
You can specify a particular date by passing an ISO-8601 date string with a year within the inclusive range 0 through 9999 to the new Date() constructor or the ISODate() function. These functions accept the following formats:
new Date("<YYYY-mm-dd>") returns the ISODate with the specified date.
new Date("<YYYY-mm-ddTHH:MM:ss>") specifies the datetime in the client’s local timezone and returns the ISODate with the specified datetime in UTC.
new Date("<YYYY-mm-ddTHH:MM:ssZ>") specifies the datetime in UTC and returns the ISODate with the specified datetime in UTC.
new Date() specifies the datetime as milliseconds since the Unix epoch (Jan 1, 1970), and returns the resulting ISODate instance.
If you are writing code in JavaScript and if you want to pass a JavaScript date object and use it with MongoDB client, the first thing you do is convert JavaScript date to MongoDB date format (ISODate). Here’s how you do it.
var today = moment(new Date()).format('YYYY-MM-DD[T00:00:00.000Z]');
console.log("Next day -- " + (reqDate.getDate() + 1))
var d = new Date();
d.setDate(reqDate.getDate() + 1);
var tomorrow = moment(d).format('YYYY-MM-DD[T00:00:00.000Z]');
You can pass today and tomorrow object to MongoDB queries with new Date() shell method.
MongoClient.connect(con, function (err, db) {
if (err) throw err
db.collection('orders').find({ "order_id": store_id, "orderDate": {
"$gte": new Date(today), "$lt": new Date(tomorrow)}
}).toArray(function (err, result) {
console.log(result);
if (err) throw err
res.send(result);
})
})

I would like to update one point from my mistake.
check if you have missed leading zero for a single digit time.
"2017-01-01T8:00:00" is invalid and will give the mentioned error.
"2017-01-01T08:00:00" is valid

Related

How to format 2022-04-11T11:56-56-07:00 [duplicate]

I have a mongo database set up.
creating a new date object in mongoDb create a date object in ISO format
eg: ISODate("2012-07-14T00:00:00Z")
I am using node.js to connect to mongo database and query the database.
when ever I create a new date object (new Date()) in javascript its creates a javascript date object eg: Wed Mar 06 2013 14:49:51 GMT-0600 (CST)
Is there a way to create an ISO date object in javascript so that I can send the object directly to the mongoDb and perform date query
I am able to perform the below query in mongoDb
db.schedule_collection.find({
start_date: { '$gte': new Date(2012, 01, 03, 8, 30) }
})
but cannot perform when I send in an javascript date object from node
The mongodb cookbook provides an python example to query the mongo database using datetime module, but does not provide any example use javascript.
Any help is appreciated.
Thanking you in advance
Try using the ISO string
var isodate = new Date().toISOString()
See also: method definition at MDN.
try below:
var temp_datetime_obj = new Date();
collection.find({
start_date:{
$gte: new Date(temp_datetime_obj.toISOString())
}
}).toArray(function(err, items) {
/* you can console.log here */
});
In node, the Mongo driver will give you an ISO string, not the object. (ex: Mon Nov 24 2014 01:30:34 GMT-0800 (PST)) So, simply convert it to a js Date by: new Date(ISOString);
I solved this problem instantiating a new Date object in node.js:...
In Javascript, send the Date().toISOString() to nodejs:...
var start_date = new Date(2012, 01, 03, 8, 30);
$.ajax({
type: 'POST',
data: { start_date: start_date.toISOString() },
url: '/queryScheduleCollection',
dataType: 'JSON'
}).done(function( response ) { ... });
Then use the ISOString to create a new Date object in nodejs:..
exports.queryScheduleCollection = function(db){
return function(req, res){
var start_date = new Date(req.body.start_date);
db.collection('schedule_collection').find(
{ start_date: { $gte: start_date } }
).toArray( function (err,d){
...
res.json(d)
})
}
};
Note: I'm using Express and Mongoskin.
This worked for me:
var start = new Date("2020-10-15T00:00:00.000+0000");
//or
start = new date("2020-10-15T00:00:00.000Z");
collection.find({
start_date:{
$gte: start
}
})...etc
new Date(2020,9,15,0,0,0,0) may lead to wrong date: i mean non ISO format
(remember javascript count months from 0 to 11 so it's 9 for october)

Troubleshooting a Date That Won't Parse in Javascript

Getting date properties back from a C# web API that seemed fine but ran into issues when plugging it into DevExtreme DateBox. It was throwing an error of 'getFullYear is not a function' so I checked the dates against this function I found here -
let r: any = http.post('/get', { Param1: 2, Param2: 1 });
console.log(r.StartDate);
console.log(this.isValidDate(r.StartDate));
r.StartDate = new Date(r.StartDate);
r.EndDate = moment(r.EndDate);
console.log('Start Date', this.isValidDate(r.StartDate));
console.log('End Date', this.isValidDate(r.EndDate));
isValidDate(d: any): void {
if (Object.prototype.toString.call(d) === "[object Date]") {
console.log('it is a date');
if (isNaN(d)) { // d.getTime() or d.valueOf() will also work
console.log('date object is not valid');
} else {
console.log('date object is valid');
}
} else {
console.log('not a date object');
}
}
StartDate: "/Date(1657512000000)/"
not a date object
undefined
it is a date
date object is not valid
Start Date undefined
not a date object
End Date undefined
Not sure why this hasn't come up before with this API but didn't want to look to DevExpress given that I can't produce a valid date.
I'm providing this answer to demonstrate one way to parse out the timestamp in the string you have of the following format, inferred by console.log(r.StartDate); ... /Date(TS)/:
// Provided the date has the following structure in a string
var anyStartDate = "/Date(1657512000000)/";
// Prepare to parse it out by getting the positions of the parentheses
var openParens = anyStartDate.indexOf("(");
var closeParens = anyStartDate.indexOf(")");
// Parse out the timestamp
var timeStampStr = anyStartDate.substring(openParens + 1, closeParens);
console.log( timeStampStr ); // 1657512000000
// Convert timestamp to an int. You can do this when you create the obj, but I am separating it here for explanation purposes.
var timeStampInt = parseInt( timeStampStr );
// Now create a date object
var dateObj = new Date( timeStampInt );
console.log( dateObj );
// (on the machine I'm on):
// Outputs: Mon Jul 11 2022 00:00:00 GMT-0400 (Eastern Daylight Time)
// Or outputs: 2022-07-11T04:00:00.000Z
Now I don't know which library(ies) you are using to handle dates so I just went with the native Date object. You can use this SOLUTION however on further insights to apply it to your code.
The point is once the timestamp is extracted, it can be then used to create a Date object, and thus utilize all the methods that are inherent to that class.
In terms of the "timezone", to get it to UTC, it's already in UTC but javascript formats it to your computer's locale. Internally it's still UTC. There's a way to display it as strictly UTC which is in the docs.
`

How can i format the date with Momentjs to look like this?

I used the following date format with a moment to save a date for a document in MongoDB. The problem is that it somehow got converted, I guess by MongoDB. Now if I want to fetch that data by specifying the date, I can't use the same variables I used to create the date in the first place. Can anyone tell me how I can do this?
const date = new Date();
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
const startDate = moment(firstDay);
const day = startDate;
the day variable is saved in MongoDB as
'Wed Jun 24 2020 00:00:00 GMT+0300'
But if I try to find the document by date, the day variable is actually returning
2020-06-24T22:17:09+03:00
I guess what I am trying to do is return today's date in this format 'Wed Jun 24 2020 00:00:00 GMT+0300' with time set to 0 as I only need the date to search for the document I need.
EDIT: I was able to do it using Date instead of Momentjs.
const date = new Date();
date.setHours(0, 0, 0, 0);
console.log(date.toString().split("(Eastern European Summer Time)")[0]);
//Wed Jun 24 2020 00:00:00 GMT+0300
You can use $dateFromString in aggregation pipeline to achieve it.
Your query might looks similar to this:
db.collection.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date'
format:<formatStringExpression>
} ] )
From official MongoDB docs:
New in version 3.6.
Converts a date/time string to a date object.
The $dateFromString expression has the following syntax:
{ $dateFromString: {
dateString: <dateStringExpression>,
format: <formatStringExpression>,
timezone: <tzExpression>,
onError: <onErrorExpression>,
onNull: <onNullExpression>
} }
You might also want to look at $dateToString in aggregation pipeline, which gives the formatted date string
The syntax is similar to above:
db.collection.aggregate( [ {
$project: {
date: {
$dateToString: {
dateString: '$date'
format:<formatString>
} ] )

Check if a date string is in ISO and UTC format

I have a string with this format 2018-02-26T23:10:00.780Z I would like to check if it's in ISO8601 and UTC format.
let date= '2011-10-05T14:48:00.000Z';
const error;
var dateParsed= Date.parse(date);
if(dateParsed.toISOString()==dateParsed && dateParsed.toUTCString()==dateParsed) {
return date;
}
else {
throw new BadRequestException('Validation failed');
}
The problems here are:
I don't catch to error message
Date.parse() change the format of string date to 1317826080000 so to could not compare it to ISO or UTC format.
I would avoid using libraries like moment.js
Try this - you need to actually create a date object rather than parsing the string
NOTE: This will test the string AS YOU POSTED IT.
YYYY-MM-DDTHH:MN:SS.MSSZ
It will fail on valid ISO8601 dates like
Date: 2018-10-18
Combined date and time in UTC: 2018-10-18T08:04:30+00:00 (without the Z and TZ in 00:00)
2018-10-18T08:04:30Z
20181018T080430Z
Week: 2018-W42
Date with week number: 2018-W42-4
Date without year: --10-18 (last in ISO8601:2000, in use by RFC 6350[2])
Ordinal date: 2018-291
It will no longer accept INVALID date strings
function isIsoDate(str) {
if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(str)) return false;
const d = new Date(str);
return d instanceof Date && !isNaN(d) && d.toISOString()===str; // valid date
}
console.log(isIsoDate('2011-10-05T14:48:00.000Z'))
console.log(isIsoDate('2018-11-10T11:22:33+00:00'));
console.log(isIsoDate('2011-10-05T14:99:00.000Z')); // invalid time part
let date= '2011-10-05T14:48:00.000Z';
var dateParsed= new Date(Date.parse(date));
//dateParsed
//output: Wed Oct 05 2011 19:48:00 GMT+0500 (Pakistan Standard Time)
if(dateParsed.toISOString()==date) {
//Date is in ISO
}else if(dateParsed.toUTCString()==date){
//DATE os om UTC Format
}
I think what you want is:
let date= '2011-10-05T14:48:00.000Z';
const dateParsed = new Date(Date.parse(date))
if(dateParsed.toUTCString() === new Date(d).toUTCString()){
return date;
} else {
throw new BadRequestException('Validation failed');
}
I hope that is clear!

Create an ISO date object in javascript

I have a mongo database set up.
creating a new date object in mongoDb create a date object in ISO format
eg: ISODate("2012-07-14T00:00:00Z")
I am using node.js to connect to mongo database and query the database.
when ever I create a new date object (new Date()) in javascript its creates a javascript date object eg: Wed Mar 06 2013 14:49:51 GMT-0600 (CST)
Is there a way to create an ISO date object in javascript so that I can send the object directly to the mongoDb and perform date query
I am able to perform the below query in mongoDb
db.schedule_collection.find({
start_date: { '$gte': new Date(2012, 01, 03, 8, 30) }
})
but cannot perform when I send in an javascript date object from node
The mongodb cookbook provides an python example to query the mongo database using datetime module, but does not provide any example use javascript.
Any help is appreciated.
Thanking you in advance
Try using the ISO string
var isodate = new Date().toISOString()
See also: method definition at MDN.
try below:
var temp_datetime_obj = new Date();
collection.find({
start_date:{
$gte: new Date(temp_datetime_obj.toISOString())
}
}).toArray(function(err, items) {
/* you can console.log here */
});
In node, the Mongo driver will give you an ISO string, not the object. (ex: Mon Nov 24 2014 01:30:34 GMT-0800 (PST)) So, simply convert it to a js Date by: new Date(ISOString);
I solved this problem instantiating a new Date object in node.js:...
In Javascript, send the Date().toISOString() to nodejs:...
var start_date = new Date(2012, 01, 03, 8, 30);
$.ajax({
type: 'POST',
data: { start_date: start_date.toISOString() },
url: '/queryScheduleCollection',
dataType: 'JSON'
}).done(function( response ) { ... });
Then use the ISOString to create a new Date object in nodejs:..
exports.queryScheduleCollection = function(db){
return function(req, res){
var start_date = new Date(req.body.start_date);
db.collection('schedule_collection').find(
{ start_date: { $gte: start_date } }
).toArray( function (err,d){
...
res.json(d)
})
}
};
Note: I'm using Express and Mongoskin.
This worked for me:
var start = new Date("2020-10-15T00:00:00.000+0000");
//or
start = new date("2020-10-15T00:00:00.000Z");
collection.find({
start_date:{
$gte: start
}
})...etc
new Date(2020,9,15,0,0,0,0) may lead to wrong date: i mean non ISO format
(remember javascript count months from 0 to 11 so it's 9 for october)

Categories

Resources