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)
Related
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>
} ] )
I have a date object that's created by the user, with the timezone filled in by the browser, like so:
var date = new Date(2011, 05, 07, 04, 0, 0);
> Tue Jun 07 2011 04:00:00 GMT+1000 (E. Australia Standard Time)
When I stringify it, though, the timezone goes bye-bye
JSON.stringify(date);
> "2011-06-06T18:00:00.000Z"
The best way I can get a ISO8601 string while preserving the browser's timezone is by using moment.js and using moment.format(), but of course that won't work if I'm serializing a whole command via something that uses JSON.stringify internally (in this case, AngularJS)
var command = { time: date, contents: 'foo' };
$http.post('/Notes/Add', command);
For completeness, my domain does need both the local time and the offset.
Assuming you have some kind of object that contains a Date:
var o = { d : new Date() };
You can override the toJSON function of the Date prototype. Here I use moment.js to create a moment object from the date, then use moment's format function without parameters, which emits the ISO8601 extended format including the offset.
Date.prototype.toJSON = function(){ return moment(this).format(); }
Now when you serialize the object, it will use the date format you asked for:
var json = JSON.stringify(o); // '{"d":"2015-06-28T13:51:13-07:00"}'
Of course, that will affect all Date objects. If you want to change the behavior of only the specific date object, you can override just that particular object's toJSON function, like this:
o.d.toJSON = function(){ return moment(this).format(); }
I'd always be inclined to not mess with functions in the prototype of system objects like the date, you never know when that's going to bite you in some unexpected way later on in your code.
Instead, the JSON.stringify method accepts a "replacer" function (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) which you can supply, allowing you to override the innards of how JSON.stringify performs its "stringification"; so you could do something like this;
var replacer = function(key, value) {
if (this[key] instanceof Date) {
return this[key].toUTCString();
}
return value;
}
console.log(JSON.stringify(new Date(), replacer));
console.log(JSON.stringify({ myProperty: new Date()}, replacer));
console.log(JSON.stringify({ myProperty: new Date(), notADate: "I'm really not", trueOrFalse: true}, replacer));
Based on Matt Johnsons 's answer, I re-implemented toJSON without having to depend on moment (which I think is a splendid library, but a dependency in such a low level method like toJSON bothers me).
Date.prototype.toJSON = function () {
var timezoneOffsetInHours = -(this.getTimezoneOffset() / 60); //UTC minus local time
var sign = timezoneOffsetInHours >= 0 ? '+' : '-';
var leadingZero = (Math.abs(timezoneOffsetInHours) < 10) ? '0' : '';
//It's a bit unfortunate that we need to construct a new Date instance
//(we don't want _this_ Date instance to be modified)
var correctedDate = new Date(this.getFullYear(), this.getMonth(),
this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds(),
this.getMilliseconds());
correctedDate.setHours(this.getHours() + timezoneOffsetInHours);
var iso = correctedDate.toISOString().replace('Z', '');
return iso + sign + leadingZero + Math.abs(timezoneOffsetInHours).toString() + ':00';
}
The setHours method will adjust other parts of the date object when the provided value would "overflow". From MDN:
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly. For example, if you use 100 for secondsValue, the minutes will be incremented by 1 (minutesValue + 1), and 40 will be used for seconds.
When I stringify it, though, the timezone goes bye-bye
That’s because Tue Jun 07 2011 04:00:00 GMT+1000 (E. Australia Standard Time) is actually the result of the toString method of the Date object, whereas stringify seems to call the toISOString method instead.
So if the toString format is what you want, then simply stringify that:
JSON.stringify(date.toString());
Or, since you want to stringify your “command” later on, put that value in there in the first place:
var command = { time: date.toString(), contents: 'foo' };
If you have a JS Date Object and want to stringify it to preserve the timezone, then you should definitely use toLocaleDateString().
It is a very powerful helper function that can help you format your Date object in every way possible.
For example, if you want to print "Friday, February 1, 2019, Pacific Standard Time",
const formatDate = (dateObject : Date) => {
const options: any = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZoneName: 'long'
};
return dateObject.toLocaleDateString('en-CA', options);
};
Thus, by modifying the options object, you can achieve different styles of formatting for your Date Object.
For more information regarding the ways of formatting, refer to this Medium article: https://medium.com/swlh/use-tolocaledatestring-to-format-javascript-dates-2959108ea020
let date = new Date(JSON.parse(JSON.stringify(new Date(2011, 05, 07, 04, 0, 0))));
I've created a small library that preserves the timezone with ISO8601 string after JSON.stringify. The library lets you easily alter the behavior of the native Date.prototype.toJSON method.
npm: https://www.npmjs.com/package/lbdate
Example:
lbDate().init();
const myObj = {
date: new Date(),
};
const myStringObj = JSON.stringify(myObj);
console.log(myStringObj);
// {"date":"2020-04-01T03:00:00.000+03:00"}
The library also gives you options to customize the serialization result if necessary.
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
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)
I am saving data in MongoDB server from Node.js application (using Mongoose).
Consider following code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schemaObj = new Schema({
field1: String,
field2: String,
Datefield: Date//So on...
});
mongooseDB = mongoose.createConnection('mongodb://myserver:port/DBname');
mongooseDB.on('error', console.error.bind(console, 'error in connection'));
mongooseDB.once('open', function (err) {
var objmodel = db.model('myschema', schemaObj);
modelObj.field1 ='value1';
modelObj.Datefield = new Date().toGMTString(); //new Date().toUTCString();
//So on..
modelObj.save(function (err) {
if (err)
//Notify err
else
//DO some task after save
});
});
In the Datefield, Getting following value when I use 'toGMTstring()' or 'toUTCstring()'
'Thu, 24 Jan 2013 05:49:04 GMT'
I went through the following links:
toUTCstring()
toGMTstring()
toGMTString is deprecated and should no longer be used
Could anyone help me in understanding, whats the difference between toUTCstring() and toGMTstring() with respect to Node.js?
GMT and UTC are different timezones, they are Greenwich Mean Time and Coordinated Universal Time respectively. GMT is a 'solar' timezone, whereas UTC is 'atomic'. For most purposes they are essentially the same thing, however UTC is more 'universal'.
Interestingly the documentation you point to for toUTCString still show a GMT output:
var today = new Date();
var UTCstring = today.toUTCString();
// Mon, 03 Jul 2006 21:44:38 GMT
For interchange of data between application I would prefer to use something like ISO8601, which uses the 'Z' suffix for UTC:
2013-01-16T08:19Z
Where the 'Z' confusingly stands for 'Zulu time'!
From what I can see they are the same. And the documentation at MDN already states that toGMTString has been deprecated in favor of toUTCString:
toGMTString() is deprecated and should no longer be used. It remains implemented only for backward compatibility; please use toUTCString() instead.
Mostly use for formatting date and time (Human Readable).
You can also use toLocaleDateString()
var event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
var options = { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' };
console.log(event.toLocaleDateString('en-US', options));
for ISO use toISOString()
var today = new Date();
var ISOstring = today.toISOString();
// 2020-08-03T23:59:58.123Z