Query by date i mongo from node.js - javascript

I want to query mongo collection by date. Example:
var startDate = new Date(dateNow.getUTCFullYear(),dateNow.getUTCMonth(),dateNow.getUTCDate(),dateNow.getUTCHours(),0);
var endDate = new Date(dateNow.getUTCFullYear(),dateNow.getUTCMonth(),dateNow.getUTCDate(),dateNow.getUTCHours()+1,0);
query.timeRegistered = { '$gte' : startDate, '$lt' : endDate };
... make mongo query ...
But it doesn't work. I assume that is because mongo saves date object in ISODate format. This query works from shell because there mongo converts Date to ISODate but from javascript (node.js) it doesn't work. I've tried all possible solutions but neither of them helped me.
Please, if anyone has any solution I would be very gratefull....

Please consider that by default the date operation in Mongo are in UTC, e.g. I entered the record in "t1" collection at June 22nd 2015 at 7:10 PM IST. however, in the shell you can see its value as 'ISODate("2015-06-22T13:40:08.545Z")' which is 5:30 hours behind. from your javascript code (which is run on the browser and hence take the browser timezone) try to create the start and end date variables as per the UTC timezone and then query the records. Let us know if it does't work, to keep it simple, give a very large date range and see if its working or not. as I am not a JS expert, I assume you may need to adjust your dates to make it in UTC.
however, tried with the Mongo client as below and it worked so I assume from JS also it should work as long you pass the date in right timezone.
db.t1.find({dt:{$gt:ISODate("2015-06-22T13:40:00.000Z"),$lt:ISODate("2015-06-22T13:41:00.000Z")} })

Related

Use moment.js to change the timezone on a datetime stamp, without changing the time

I am migrating event data from an old SQL database to a new Mongo database, using NodeJS. However, whoever set up the SQL database created all of the dates for the events, made the times in PST/PDT, but the database believes they are in UTC time.
For Example:
A date from the SQL database may be: 23-APR-10 which MomentJS shows as: 2010-04-23T21:00:00Z when 21:00:00 is the PST time.
Is it possible to use pure JavaScript/MomentJS/NodeJS or a different npm module to change the timezone on the DateTime string without modifying the time (i.e. 2010-04-23T21:00:00Z would become 2010-04-23T21:00:00-8:00)?
PS. Even though the SQL database only shows DD-MMM-YY but returns a DateTime string when I query it.
Following the line of inquiry in the question comments, it seems your problem is that due to the timezone mishap, the timestamps stored in the db are stored without the timezone offset, and since your desired timezone is PST (UTC-8hours), the timestamps are 8 hours ahead, for instance, what should have been 2010-04-23T13:00:00Z has become 2010-04-23T21:00:00Z.
So what needs to be done here is that the utc offset for your desired timezone needs to be obtained and added to the date.
The offset in your case is known (-8 hours). However, we can fetch the correct offset of any desired timezone from the moment-timezone library.
const moment_timezone = require('moment-timezone');
//a sample timestamp you're getting from your db
const myDateObj = new Date("2010-04-23T21:00:00Z");
//timezone for PST as understood by moment-timezone
const myMomentTimezone = "America/Los_Angeles";
//offset for your timezone in milliseconds
const myTimezoneOffset = moment_timezone.tz(myMomentTimezone).utcOffset()*60000;
//perfom the correction
const getCorrectedDateObj = (givenDateObj) => new Date(givenDateObj.valueOf() + myTimezoneOffset);
console.log(getCorrectedDateObj(myDateObj));
You may notice that we are actually changing the timestamp, because the given timestamp and the requried timestamp are, due to the nature of the error, essentially different timestamps. Moment-timezone is only being used here to fetch the offset, it's not used to "convert" anything.
Anuj Pancholi's answer is correct, however; the old SQL database I'm using seems to have a lot of quirks, so I had to modify his answer to get my code working.
My Solution:
function getCorrectedDateObj(myDateObj){
const timezoneOffset = momentTimeZone.tz(timezone).utcOffset() * 60000;
const dt = new Date(myDateObj.valueOf() + timezoneOffset / 2);
dt.setHours(dt.getHours() + 12);
}

Sequelize behavior on DateTime

The datetime in table is 2018-01-03 15:46:59.807438 in postgres. But the result from sequelize shows time as 2018-01-03T20:46:59.807Z. I don't see any manual conversion done. Could you please help understand reason why. Somewhere i feel the time is converted to/from UTC
In Postgres datetime shown in local timezone (to see current timezone: show timezone;). Response from sequelize shown in zero timezones (Z at the end of the date, ref: https://www.timeanddate.com/time/zones/z). So, it's the same date, but the first one is the date in your local timezone, the second one - UTC.

Convert hour to date time without adding +1

Hi im using moment js to convert this string 20:00 I tried:
var a = moment("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00+01:00
the problem when I store in mongodb it become
2016-09-10T19:00:00.000Z
I want to store 2016-09-10T20:00:00.000Z
anyway can explain why please ?
When you say that you want to store 2016-09-10T20:00:00.000Z what you are saying is that you want to assume that your date and time is UTC.
To assume that the date you are parsing is a UTC value, use moment.utc
var a = moment.utc("20:00", "HH:mm")
console.log(a.format()) // 2016-09-08T20:00:00Z
Note that when you parse a time without a date, moment assumes the current date. This may not be the behavior that you want.
I'm also not sure if you want a UTC date (which is what you are saying), or a local date without an offset indicator. If you want a local date without an offset indicator, simply use a format without an offset:
moment.utc("20:00", "HH:mm").format('YYYY-MM-DDTHH:mm:ss.SSS')
"2016-09-08T20:00:00.000"
If you are dealing with local dates that do not have a time zone association, I recommend using moment.utc to parse, as this will ensure that the time does not get shifted to account for DST in the current time zone.
For more information about how to parse dates into the time zone or offset that you would like in moment, see my blog post on the subject.
This it how it should look:
var a = moment("20:00", "HH:mm")
console.log(a.utcOffset('+0000').format())
<script src="http://momentjs.com/downloads/moment.min.js"></script>
Doe, the problem is that you are using timezones when you create the date.
MomentJS uses your current timezone automatically.
Mongo however saves the time as it would be in another timezone.
Therefore, if you want the two strings to format the same way, you need to set the timezone.

Mongoose.js find yesterday's date in database

I want to find all the users created up until yesterday. This is my code to make the query string:
var today = new Date();
var a = today.getDate();
a--;
today.setDate(a);
var yesterday = today.toDateString();
and it returns something like: Sun Jan 17 2016... which IS yesterday's date, but the db stores the date in iso format like: "date" : ISODate("2016-01-13T13:23:08.419Z") so what I get is 2016-01-13T13:23:08.419Z. My problem now is that I can't use the yesterday variable to query the db for the users I need AND even if I could, I don't know how to find every registration not including the ones that took place today.
Any help? Thank you very much!
You are generating a date on the front end, and then pushing it back a day, which is totally fine for a lot of circumstances -
For this, since you are trying to find DB entries that occured, perhaps try querying the database with a timestamp ranged pulled from the ID's of each document in your database.
Here is some documentation on how to do that from mongoDB. https://docs.mongodb.org/v3.0/reference/method/ObjectId.getTimestamp/
I've also provided some additional resources that may help you figure out exactly what to query in regard to this method:
https://steveridout.github.io/mongo-object-time/
https://gist.github.com/tebemis/0e55aa0089e928f362d9
Some psuedo code:
1. Query documents in the database
2. Get a timestamp from the ID's of the documents in the database
3. Set a range of the timestamps
4. Compare returned timestamps vs a timestamp range variable (yesterdays date in this case)
5. Have the DB return only documents that are within the range
I hope this helps!
Try this, using Moment.js:
yesterday = moment().add(-1, 'days');
db.users.find({ "date": { "$lt": yesterday }});
Create a date object that represents the start of day today, use it to query your collection for documents where the date field is less than that variable, as in the following example
var start = new Date();
start.setHours(0,0,0,0);
db.users.find({ "date": { "$lt": start }});
This will look for users created up until end of day yesterday.
momentjs is a super handy utility for doing manipulations like this. Using the library, this can be achieved with the startOf() method on the moment's current date object, passing the string 'day' as arguments:
Local GMT:
var start = moment().startOf('day'); // set to 12:00 am today
db.users.find({ "date": { "$lt": start }});
For UTC:
var start = moment.utc().startOf('day');

How to get difference of saved time and current time in jquery?

I want to get the time difference between saved time and current time in javascript or jquery. My saved time looks like Sun Oct 24 15:55:56 GMT+05:30 2010.
The date format code in java looks like
String newDate = "2010/10/24 15:55:56";
DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = format.parse(newDate);
How to compare it with the current time and get the difference?
Is there any inbuilt function in jquery or javascript??
Any suggestions or links would be appreciative!!!
Thanks in Advance!
Update
Date is stored as varchar in the DB. I am retriving it to a String variable and then change it to java.util.Date object. The java code looks like
String newDate = "2010/10/24 15:55:56";
DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = format.parse(newDate);
This date object was sent to client. There i want to compare the saved date with current date and want to show the time difference like 2 secs ago, 2 hours ago, 2 days ago etc... like exactly in facebook. I have gone through some date to timestamp conversion tutorial in java script and now i can get the difference in timestamp. Now, i want to know how i shall change it to some format like "2 secs or 2 days or 24 hours"??. Or, how i shall change it back to date format???
Convert them into timestamps which are actually integers and can get subtracted from each other. The you just have to convert back the resulting timestamp to a javascript date object.
var diff = new Date();
diff.setTime( time2.getTime()-time1.getTime() );
You dont need to explicit convert, just do this:
var timediff = new Date() - savedTime;
This will return the difference in milliseconds.
jQuery doesn't add anything for working with dates. I'd recommend using Datejs in the event that the standard JavaScript Date API isn't sufficient.
Perhaps you could clarify exactly what input and output you're aiming for. What do you mean by "the difference?" There is more than one way to express the difference between to instants in time (primarily units and output string formatting).
Edit: since you said you're working with jQuery, how about using CuteTime? (Demo page)

Categories

Resources