I have a date stored in a database as a string. It looks like this:
Tue Aug 23 2016 00:00:00 GMT-0500 (CDT)
I basically want to tell if today's date is before or after the date in the database.
The code below should sort of explain what I want. The problem is that after the difference variable doesn't return a number variable, which is what I need.
var expire = value.vaccines;
var today = new Date();
var difference = today-expire;
if(difference <= 0){
$(element).css({"color": "#0040ff"});
}
Any ideas on how to subtract these two dates and get a number value?
Assuming both your objects are Date
Although you only require the returned value in milliseconds, I've added the extra step of formatting the value.
Math.floor((today - expire) / (1000*60*60*24))
Taken from Here
You can just you can calculate the difference between the two Date objects and get the absolute value with Math.abs():
var today = new Date(),
expire = value.vaccines,
difference = Math.abs(today - expire); // difference in milliseconds
if (difference <= 0) {
$(element).css({
"color": "#0040ff"
});
}
Check that expire is a valid Date object.
Related
I observed some strange Date behaviour in Chrome (Version 74.0.3729.131 (Official Build) (64-bit)).
Following javascript was executed in the Chrome Dev Console:
new Date('1894-01-01T00:00:00+01:00')
// result: Mon Jan 01 1894 00:00:00 GMT+0100 (Central European Standard Time)
new Date('1893-01-01T00:00:00+01:00')
// result: Sat Dec 31 1892 23:53:28 GMT+0053 (Central European Standard Time)
I have already read about non standard date parsing via the Date ctor in different browsers, although providing valid ISO8601 values.
But this is more than strange o_o
In Firefox (Quantum 66.0.3 (64-Bit)) the same calls result in expected Date objects:
new Date('1894-01-01T00:00:00+01:00')
// result: > Date 1892-12-31T23:00:00.000Z
new Date('1893-01-01T00:00:00+01:00')
// result: > Date 1893-12-31T23:00:00.000Z
Is this a bug in Chrome?
My input is valid ISO8601 i guess?
The most important question is, how do I fix this? (hopefully without parsing the input string myself)
Okay, seems like this behaviour cannot be avoided, so you should parse dates manually. But the way to parse it is pretty simple.
If we are parsing date in ISO 8601 format, the mask of date string looks like this:
<yyyy>-<mm>-<dd>T<hh>:<mm>:<ss>(.<ms>)?(Z|(+|-)<hh>:<mm>)?
1. Getting date and time separately
The T in string separates date from time. So, we can just split ISO string by T
var isoString = `2019-05-09T13:26:10.979Z`
var [dateString, timeString] = isoString.split("T")
2. Extracting date parameters from date string
So, we have dateString == "2019-05-09". This is pretty simple now to get this parameters separately
var [year, month, date] = dateString.split("-").map(Number)
3. Handling time string
With time string we should make more complex actions due to its variability.
We have timeString == "13:26:10Z"
Also it's possible timeString == "13:26:10" and timeString == "13:26:10+01:00
var clearTimeString = timeString.split(/[Z+-]/)[0]
var [hours, minutes, seconds] = clearTimeString.split(":").map(Number)
var offset = 0 // we will store offset in minutes, but in negation of native JS Date getTimezoneOffset
if (timeString.includes("Z")) {
// then clearTimeString references the UTC time
offset = new Date().getTimezoneOffset() * -1
} else {
var clearOffset = timeString.split(/[+-]/)[1]
if (clearOffset) {
// then we have offset tail
var negation = timeString.includes("+") ? 1 : -1 // detecting is offset positive or negative
var [offsetHours, offsetMinutes] = clearOffset.split(":").map(Number)
offset = (offsetMinutes + offsetHours * 60) * negation
} // otherwise we do nothing because there is no offset marker
}
At this point we have our data representation in numeric format:
year, month, date, hours, minutes, seconds and offset in minutes.
4. Using ...native JS Date constructor
Yes, we cannot avoid it, because it is too cool. JS Date automatically match date for all negative and too big values. So we can just pass all parameters in raw format, and the JS Date constructor will create the right date for us automatically!
new Date(year, month - 1, date, hours, minutes + offset, seconds)
Voila! Here is fully working example.
function convertHistoricalDate(isoString) {
var [dateString, timeString] = isoString.split("T")
var [year, month, date] = dateString.split("-").map(Number)
var clearTimeString = timeString.split(/[Z+-]/)[0]
var [hours, minutes, seconds] = clearTimeString.split(":").map(Number)
var offset = 0 // we will store offset in minutes, but in negation of native JS Date getTimezoneOffset
if (timeString.includes("Z")) {
// then clearTimeString references the UTC time
offset = new Date().getTimezoneOffset() * -1
} else {
var clearOffset = timeString.split(/[+-]/)[1]
if (clearOffset) {
// then we have offset tail
var negation = timeString.includes("+") ? 1 : -1 // detecting is offset positive or negative
var [offsetHours, offsetMinutes] = clearOffset.split(":").map(Number)
offset = (offsetMinutes + offsetHours * 60) * negation
} // otherwise we do nothing because there is no offset marker
}
return new Date(year, month - 1, date, hours, minutes + offset, seconds)
}
var testDate1 = convertHistoricalDate("1894-01-01T00:00:00+01:00")
var testDate2 = convertHistoricalDate("1893-01-01T00:00:00+01:00")
var testDate3 = convertHistoricalDate("1894-01-01T00:00:00-01:00")
var testDate4 = convertHistoricalDate("1893-01-01T00:00:00-01:00")
console.log(testDate1.toLocaleDateString(), testDate1.toLocaleTimeString())
console.log(testDate2.toLocaleDateString(), testDate2.toLocaleTimeString())
console.log(testDate3.toLocaleDateString(), testDate3.toLocaleTimeString())
console.log(testDate4.toLocaleDateString(), testDate4.toLocaleTimeString())
Note
In this case we are getting Date instance with all its own values (like .getHours()) being normalized, including timezone offset. The testDate1.toISOString will still return weird result. But if you are working with this date, it will probably 100% fit your needings.
Hope that helped :)
This might be the case when all browsers follow their own standards for encoding date formats (but I am not sure on this part). Anyways a simple fix for this is to apply the toISOString method.
const today = new Date();
console.log(today.toISOString());
I had two ical format timestamps and I want to convert them to normal time first and then to unix time.
Here this is the function I've been using to convert normal time to unix timestamp:
var normal_to_unix = function (date_string) {
var date = new Date(date_string);
return date.getTime() / 1000;
}
This function is fine since date is already in UTC and I need not do any conversions.
Now this is the function I've been using to convert ical time to unix time. The ical time in my case is like "20180603T150000Z".
var ics_to_unix = function (ics_string) {
var year = ics_string.slice(0, 4);
var month = ics_string.slice(4, 6);
var date = ics_string.slice(6, 8);
var hours = ics_string.slice(9, 11);
var minutes = ics_string.slice(11, 13);
var seconds = ics_string.slice(13, 15);
var milliseconds = 0;
console.log(year, month, date, hours, minutes, seconds, milliseconds); // This is example output 2018 06 03 15 00 00 0
return normal_to_unix((new Date(year, month, date, hours, minutes, seconds, milliseconds)).toDateString())
}
Now the problem is I'm getting the same unix time for "20180603T150000Z" and "20180603T160000Z" which are supposed to give different timestamps and it is 1530576000 for both of them.
Is there anything that I'm missing ? Thanks in advance.
Please have a look at this for live example
Several points here:
The toDateString() method returns the date portion of a Date object in human readable form in American English. For your example it is `Tue Jul 03 2018', perhaps that is not what you want.
new Date creates date in your local timezone, which could play well if you use it together with toString(), which will also return the string for date in your local timezone. But it will be subject to daylight saving changes, so I'd avoid using that method.
Another thing I'd like to avoid converting back and forth between strings and dates, since it does a lot of unnecessary computations.
I'd suggest to use the following:
var ics_to_unix = function (ics_string) {
var year = parseInt(ics_string.slice(0, 4));
var month = parseInt(ics_string.slice(4, 6)) - 1; // Jan is 0
var date = parseInt(ics_string.slice(6, 8));
var hours = parseInt(ics_string.slice(9, 11));
var minutes = parseInt(ics_string.slice(11, 13));
var seconds = parseInt(ics_string.slice(13, 15));
return Date.UTC(year, month, date, hours, minutes, seconds) / 1000;
}
I have added explicit conversion of strings to numbers, adjusted the month to match what is used in javascript and also removed the extra call.
I'm trying to get number of days passed. I'm storing epoch (milliseconds) for date.
I'm reading startDate from database (date value of first record) in milliseconds and I want to find current epoch in specified timezone.
I tried this:
var startDate = rows[0]['MIN_DATE'];
var endDate = moment().tz("America/New_York");
Then to calculate difference, I used:
var oneDay = 24 * 60 * 60 * 1000;
var daysCount = Math.ceil((endDate - startDate) / (oneDay));
The value of startDate is:
1522821600000 which is: Wednesday, April 4, 2018 2:00:00 AM GMT-04:00 DST
The value of endDate is:
Moment_d: Wed Apr 04 2018 22:24:45 GMT-0400 (EDT)_isAMomentObject: true_isUTC: true_isValid: true_locale: Locale_offset: -240_pf: Object_z: Zone__proto__: Object
The value of daysCount is 2, how?
How can I get milliseconds instead of object from:
moment().tz("America/New_York");
To directly answer your question, use .valueOf() to get the value of moment.tz("America/New_York")
var endDate = moment.tz("America/New_York").valueOf()
I'm having difficulty understanding your question, but I believe you're trying to get the difference between the days considering the correct timezone. The following gives an accurate result using .diff() (https://momentjs.com/docs/#/displaying/difference/)
var timeZone = "America/New_York"
var startDate = 1522821600000
var momentStartDate = moment.tz(startDate,timeZone)
var momentEndDate = moment.tz(timeZone)
alert(momentEndDate.diff(momentStartDate, 'days') );
Use fromNow() function. It is very straight-forward.
Do like this :
moment(date).fromNow();
It will give you number of days passed if date is past as well as number of days to go if date is future.
Below are is example:
var date = 1522821600000; // your date
console.log(moment(date).fromNow());
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
Solved this with following statement:
var endDate = moment().tz("America/New_York").valueOf();
I want to find all document's created since midnight, regardless of the users timezone. If the users on Pacific time, it should show all their documents since midnight Pacific. Same with Eastern time.
I'm on Eastern time and this works for me:
var d = new Date();
var midnight = d.setHours(0,0,0,0); // last midnight
var count = Items.find({
username: Meteor.user().username,
createdAt: { $gt: midnight }
}).count();
But my client is on CST and it doesn't work for him. It instead shows documents created since like 10pm or 11pm CST the previous day. So this seems like a timezone issue for me.
Assuming that this is a client-side issue only (all of the times are stored in UTC on the server) then you can get the UTC adjusted time for midnight of the users current timezone by doing the following:
var now = new Date();
var midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var midnight_utc = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
See this fiddle: https://jsfiddle.net/Lbk1vo0j/1/
For example, for my current time zone (eastern) I get the following values for now, midnight, and midnight_utc (when printing the Date objects using the toLocaleString() method):
3/30/2015, 3:06:39 PM
3/30/2015, 12:00:00 AM
3/29/2015, 8:00:00 PM
try setUTCHours(0, 0, 0, 0);. It gets the Coordinated Universal Time that should be the same for every user.
I had similar requirement so I did used following method,
Created function to map datetime to _id
used that id to get my data.
Function that I am using is
function objectIdWithTimestamp(timestamp){
// Convert string date to Date object (otherwise assume timestamp is a date)
if (typeof(timestamp) == 'string') { timestamp = new Date(timestamp); }
// Convert date object to hex seconds since Unix epoch
var hexSeconds = Math.floor(timestamp/1000).toString(16);
// Create an ObjectId with that hex timestamp
var constructedObjectId = ObjectId(hexSeconds + "0000000000000000");
return constructedObjectId
}
using it
db.collection.find({_id:{$gte:objectIdWithTimestamp(Y/m/d H:i:s)}})
I will advice you try moment library and resolve the time zone problem. Where ever client code is getting executed, get its last midnight time, convert it to UTC time & then easily retrieve the information from MongoDb. Few moment library usage example, for more detail refer here
var str = "2013-12-01"
moment.tz(str, "America/Los_Angeles").format(); // 2013-06-01T00:00:00-07:00
moment.tz(str, "America/New_York").format(); // 2013-06-01T00:00:00-04:00
Minutes since midnight
You can get the minutes since midnight from the user's perspective. Try using it to query the server for changes since x minutes ago.
var d = new Date();
console.log(d);
var now = d.getTime();
d.setHours(0,0,0,0);
var midnight = d.getTime();
var minutes_ago = Math.floor((now-midnight) / (60 * 1000));
console.log(minutes_ago);
output:
Date {Thu Apr 02 2015 16:12:54 GMT-0700 (PDT)}
972
This should work:
var d = new Date();
var midnight = d.setUTCHours(0,0,0,0); // last midnight everywhere
var count = Items.find({
username: Meteor.user().username,
createdAt: { $gt: midnight }
}).count();
The UTC thing is really making me crazy... I am trying to have date and time on site in UTC so it has no affect of any timezone.
What I do, I create a date object
var d = new Date();
//convert it to utc
var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
var utc_date = new Date(utc);
utc_date.setHours(20,0,0)
console.log(utc_date.getTime()) // I want this to be same irrespective of timezone, but don't know why it is changing
Please guide where I am doing wrong..?
UPDATED:
I wanted to create a dropdown of time like on http://jsfiddle.net/HNyj5/ the concept here is I use a timestamp either from client side of selected date or from db and then I generate this dropdown dynamically. So I want the timestamp to be similar on both server/client thats why I am trying to use UTC date object.
You can retrieve the UTC datetime from local time like this (example timezone = GMT+0100):
var currentUTC = new Date; //=>Mon Mar 18 2013 13:53:24
currentUTC.setMinutes(currentUTC.getMinutes()+currentUTC.getTimezoneOffset();
//=> currentUTC now: Mon Mar 18 2013 12:54:06
//or
var someUTC = new Date('1998/03/18 13:52'); //=> Wed Mar 18 1998 13:52:00
someUTC.setMinutes(currentUTC.getMinutes()+currentUTC.getTimezoneOffset();
//=> someUTC now: Wed Mar 18 1998 12:52:00
Or as a Date Extension with a one liner:
Date.prototype.UTCFromLocal = function(){
var a;
return new Date(Date.prototype.setMinutes
.call(a = this,a.getMinutes()+a.getTimezoneOffset()));
}
// usage (current date and time = Mon Mar 18 2013 14:08:14 GMT+0100
var d = new Date().UTCFromLocal(); //=> Mon Mar 18 2013 13:08:14
And to retrieve (from a UTC datetime) you could use:
Date.prototype.LocalFromUTC = function(){
var a;
return new Date(Date.prototype.setMinutes
.call(a = this,a.getMinutes()-a.getTimezoneOffset()));
}
Please guide where I am doing wrong..?
You are building a utc_date that is a completely different time, somehow biased by the getTimezoneOffset. Just do
var d = new Date();
d.getTime(); // milliseconds since epoch
or
Date.now();
And if you're working in UTC-land, you should use d.setUTCHours instead of the local-timezone-dependent setHours.
Actually what I was expecting the JS to do was if I pass the timestamp in the Date constructor it should make object w.r.t that timestamp but it converts it to localtimezone which was making issues for me.
So what I did for solving this problem I get the date object by passing the string of the selected date.
var date = new Date(selected_date_str); rather than passing the timestamp
as I was making dropdown of time with UTC timestamp as its value. The start hour:min of dropdown was dynamic, which I was passing as argument in the function, it was from_hr like if I want to create dropdown of time from 20:00 then I pass from_hr = 20
so now I set hour for the selected date
date.setHours(from_hr, 0, 0);
then I made a utc_time variable for making the the value for dropdown
var utc_time = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), from_hr, 0, 0, 0);
this will retain in all timezones, this is what I am going to use as the base. Then in the loop I was adding 15 mins in the time
var count = 0;
jQuery(elem).html('');
while(count <= 95){
var option = '<option value="{0}">{1}:{2}</option>'.format(utc_time/1000, ('0' + date.getHours()).slice(-2), ('0' + date.getMinutes()).slice(-2)); //here i used a format prototype, which you can find in the jsfiddle link of my question
jQuery(elem).append(option);
utc_time += 15 * 60 * 1000; //adding 15 mins in the utc timestamp
date.setMinutes(date.getMinutes() + 15)
count++; }
I was dividing the utc_time with 1000 to make it php compatible, because I was going to retrieve value from here and save in db.