I am trying to create an if statement that can check today's date and time and if it's greater than a predefined date and time, do something. I'm looking to do this in vanilla JS only and get it to work in IE.
This is the basic working code for Chrome.
var ToDate = new Date()
if (new Date("2018-11-30 05:00").getTime() > ToDate.getTime()) {
alert("true")
} else {
alert("false")
}
How can I make something like this work in IE?
if (new Date("2018-11-30 05:00").getTime() > ToDate.getTime()) {
On firefox and chrome there are no issues with it. On Internet Explorer it's false.
On IE (or in general) the string needs to be an RFC2822 or ISO 8601 formatted date
Example:
new Date("2018-11-29T19:15:00.000Z")
If you need portable solution (eg. support older Internet Explorer) I would use this constructor instead:
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
Keep in mind that monthIndex starts from 0 (January).
Test:
function assertTrue(exp, message) {
if (exp === false) {
message = message || 'Assertion failed';
alert(message);
throw message;
}
}
function testShouldPassForDatesInTheFuture() {
var ToDate = new Date(2018, 10, 29);
assertTrue(new Date(2018, 10, 30).getTime() > ToDate.getTime());
}
function testShouldPassForDatesInThePast() {
var ToDate = new Date(2018, 10, 29);
assertTrue(new Date(2018, 10, 28).getTime() < ToDate.getTime());
}
testShouldPassForDatesInThePast();
testShouldPassForDatesInThePast();
alert('All test passed');
You need to append 'T00:00:00.000Z' to your date.
new Date("2018-11-30" + 'T00:00:00.000Z')
Full code is below:
var ToDate = new Date()
if (new Date("2018-11-30" + 'T00:00:00.000Z').getTime() > ToDate.getTime()) {
alert("true")
} else {
alert("false")
}
Your issue is that the date format YYYY-MM-DD HH:mm is not supported by ECMAScript, so parsing is implementation dependent. Safari, for example:
new Date("2018-11-30 05:00")
returns an invalid date.
You can first parse the string manually, either with a bespoke function (e.g. How to parse a string into a date object at JavaScript?) or a library, then you can compare the result with new Date() as for Compare two dates with JavaScript.
A simple parse function is not difficult:
/* Parse string in YYYY-MM-DD HH:mm:ss to a Date
* All parts after YYYY-MM are optional, milliseconds ignored
*/
function parseDate(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2]||1, b[3]||0, b[4]||0, b[5]||0);
}
["2018-11-23 17:23",
"2019-01",
"2020-12-31 23:59:59"].forEach(s => {
console.log(`${s} => ${parseDate(s).toString()}`);
});
Then you can compare dates using <, <=, > and >=.
In this case, a date like "2018-01-01" will be considered past at any time after 2018-01-01 00:00:00.000.
Alternatively, since the string is similar to ISO 8601 format, you can compare the parts of the string with a similarly formatted string for today:
// Return date string in YYYY-MM-DD HH:mm:ss format
// Only return as many parts as len, or all 6 if missing
function formatDate(d, len) {
var parts = [d.getFullYear(), '-'+d.getMonth()+1, '-'+d.getDate(), ' '+d.getHours(), ':'+d.getMinutes(), ':'+d.getSeconds()];
var spacer = ['-','-',' ',':',':'];
len = len || 6;
return parts.splice(0, len).join('');
}
['2018-06-30 12:04',
'2018-10',
'2018-12-15 03:14:45',
'2019-01-01',
'2020-12-15 03:14:45'].forEach(s => {
console.log(`${s} has passed? ${s < formatDate(new Date(), s.split(/\D/).length)}`);
});
In this case, 2018-01-01 will be equal to any date generated on that day, and "2018-01" will be equal to any date generated in January 2018. It's up to you whether you use < or <= for the comparison.
So you need to consider carefully where you draw the boundary between earlier and later and adjust the logic accordingly.
Related
I am getting a SQL date - NOT datetime - object pushed into my Javascript code, and I need to see whether it's before today or not. Here is the code I have (the relevant part):
todaysDate = new Date();
todaysDate.setHours(0,0,0,0);
var date = Date.parse(row[3]);
// date.setHours(0,0,0,0);
if (date < todaysDate) {
alert("date is before today");
dueDate = '<small class="text-danger">';
} else {
alert("date is after today");
dueDate = '<small class="text-muted">';
}
row[3] is the source of the SQL date. So, this works fine for everything except dates that are today. Without the commented line, it thinks that anything with today's date is in the past. With the commented line, my code breaks. Any thoughts as to how to fix this? Not sure what I'm doing wrong.
Thanks!
If your date string is like "2016-04-10" and your time zone is west of GMT, say -04:00, then in browsers compliant with ECMAScript 2016 you will get a Date for "2016-04-09T19:00:00-0400".
When you create a Date using new Date() and set the hours to zero (assuming it's 10 April where you are), you'll get a Date for "2016-04-10T00:00:00-0400".
So when compared they have different time values.
What you need is to either treat the string you get from the database as local, or get the UCT date where you are, so:
var dateString = '2016-04-10';
var parsedDate = new Date(dateString);
var todayUTCDate = new Date();
todayUTCDate.setUTCHours(0,0,0,0);
document.write(parsedDate + '<br>' + todayUTCDate);
But not all browsers parse strings according to ECMAScript 2015 so they should always be manually parsed. Use a library, or write a small function, e.g.
// Parse date string in format 'yyyy-mm-dd' as local date
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2]);
}
and replace:
var date = Date.parse(row[3]);
with:
var date = parseISOLocal(row[3]);
and then in the comparison, compare the time values:
if (+date < +todaysDate) {
or
if (date.getTime() < todaysDate.getTime()) {
Use getTime() of date object.
The getTime() method returns the number of milliseconds between midnight of January 1, 1970 and the specified date.
You can compare miliseconds and do your operations
date.getTime() > todaysDate.getTime()
Also be sure that Date.parse is returning a valid date.
I want to test invalid date, the function I wrote works fine in chrome but not in Firefox. Here are some examples not working in FF:
new Date('01/99/2010') = return Valid Date
new Date('99/01/2010') = return Valid Date
var day='01', month = '99', year = '2010';
new Date(year,month,day) = return Valid Date
var day='99', month = '01', year = '2010';
new Date(year,month,day) = return Valid Date
Above methods return "Invalid Date" in Chrome, but not in Firefox. Does anyone know the proper way to validate date in Firefox.
PS: Input string could be - mm/dd/yyyy or dd/mm/yyyy or yyyy/mm/dd
It looks like Firefox takes this rule one step further than Chrome:
Note: Where Date is called as a constructor with more than one
argument, if values are greater than their logical range (e.g. 13 is
provided as the month value or 70 for the minute value), the adjacent
value will be adjusted. E.g. new Date(2013, 13, 1) is equivalent to
new Date(2014, 1, 1), both create a date for 2014-02-01 (note that the
month is 0-based). Similarly for other values: new Date(2013, 2, 1, 0,
70) is equivalent to new Date(2013, 2, 1, 1, 10) which both create a
date for 2013-03-01T01:10:00.
Source - MDN Date documentation.
The emphasis here is on with more than one argument. That's why Chrome does what Firefox does for:
new Date(2010, 99, 1); - a valid date object.
but because:
new Date('01/99/2010'); is technically only a single argument, it doesn't fall for the above rule in Chrome, but Firefox allows it through.
With the above in mind, and the inconsistency across browsers, it looks like you might be stuck writing a validator for the day, month and year separately from trying to do it via the Date object if you want it to work in Firefox.
You can use regex. Try this:
var rgx = /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/;
console.log(rgx.test("99/12/2015"));
jsFiddle
I would use a internal JavaScript funtion for validating Dates, as browsers do handle those data types very differently.
function isValidDate(date)
{
var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
if (matches == null) return false;
var d = matches[2];
var m = matches[1] - 1;
var y = matches[3];
var checkDate = new Date(y, m, d);
return checkDate.getDate() == d &&
checkDate.getMonth() == m &&
checkDate.getFullYear() == y;
}
You would then use it like this:
var d = new Date(2010, 99, 1);
console.log( isValidDate(d) ); // returns false no valid date
I want to check to see if a date is before today. If it is then I want to display the date but not the time, if it is today then I want to display the time and not the date. The date I am checking is in the dd-mm-yyy hh:mm format and so they do not compare.
Please see what I have below so far:
var created = '25-05-2012 02:15';
var now = new Date();
if (created < now) {
created_format = [ format the date to be 25-05-2012 ]
} else {
created_format = [ format the date to be 02:15 ]
}
I have tried using now.dateFormat() and now.format() after seeing these in other examples but I get "is not a function" error messages.
Start by getting the parts of your date string:
var created = '25-05-2012 02:15';
var bits = created.split(/[-\s:]/);
var now = new Date();
// Test if it's today
if (bits[0] == now.getDate() &&
bits[1] == (now.getMonth() + 1) &&
bits[2] == now.getFullYear() ) {
// date is today, show time
} else {
// date isn't today, show date
}
Of course there are other ways, but I think the above is the easiest. e.g.
var otherDate = new Date(bits[2], bits[1] - 1, bits[0]);
now.setHours(0,0,0,0);
if (otherDate < now) {
// otherDate is before today
} else {
// otherDate is not before today
}
Similarly, once you've converted the string to a date you can use getFullYear, getMonth, getDate to compare with each other, but that's essentially the same as the first approach.
You can use getTime method and get timestamp. Then you can compare it with current date timestamp.
I need to validate different date's with some javascript(jquery).
I have a textbox with, the inputmask from jquery (http://plugins.jquery.com/plugin-tags/inputmask). The mask that i use is "d/m/y".
Now i have set up a CustomValidator function to validate the date.
I need 2 functions. One to check if the given date is greater then 18 years ago. You must be older then 18 year.
One function to check if the date is not in the future. It can only in the past.
The function are like
function OlderThen18(source, args) {
}
function DateInThePast(source, args) {
}
As you know the value you get back with args.Value is 27/12/1987 .
But how can i check this date in the functions? So that i can set args.IsValid to True or False.
I tried to parse the string(27/12/1987) that i get back from the masked textbox to a date but i get always a value back like 27/12/1988.
So how could I check the given dates with the other dates?
The simple way is to add 18 years to the supplied date and see if the result is today or earlier, e.g.:
// Input date as d/m/y or date object
// Return true/false if d is 18 years or more ago
function isOver18(d) {
var t;
var now = new Date();
// Set hours, mins, secs to zero
now.setHours(0,0,0);
// Deal with string input
if (typeof d == 'string') {
t = d.split('/');
d = new Date(t[2] + '/' + t[1] + '/' + t[0]);
}
// Add 18 years to date, check if on or before today
if (d.setYear && d.getFullYear) {
d.setYear(d.getFullYear() + 18);
}
return d <= now;
}
// For 27/4/2011
isOver18('27/4/2011'); // true
isOver18('26/4/2011'); // true
isOver18('28/4/2011'); // false
try this to start:
var d = new Date(myDate);
var now = new Date();
if ((now.getFullYear() - d.getFullYear()) < 18) {
//do stuff
}
The javascript date object is quite flexible and can handle many date strings.
You can compare two Date objects or use the Date interface methods, such as getSeconds() of getFullYear() in order to deduce useful data regarding the date.
See Date object reference formore details.
You'll need to construct, modify and compare Date objects - something like this:
// str should already be in dd/mm/yyyy format
function parseDate(str) {
var a = str.split('/');
return new Date(parseInt(a[2], 10), // year
parseInt(a[1], 10) - 1, // month, should be 0-11
parseInt(a[0], 10)); // day
}
// returns a date object for today (at midnight)
function today() {
var date = new Date();
date.setHours(0, 0, 0);
return date;
}
function DateInThePast(str) {
// date objects can be compared like numbers
// for equality (==) you'll need to compare the value of date.getTime()
return parseDate(str) < today();
}
function OlderThan18(str) {
// left as an exercise for the reader :-)
}
I have two dates 18-Aug-2010 and 19-Aug-2010 of this format. How to find whether which date is greater?
You will need to create a custom parsing function to handle the format you want, and get date objects to compare, for example:
function customParse(str) {
var months = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'],
n = months.length, re = /(\d{2})-([a-z]{3})-(\d{4})/i, matches;
while(n--) { months[months[n]]=n; } // map month names to their index :)
matches = str.match(re); // extract date parts from string
return new Date(matches[3], months[matches[2]], matches[1]);
}
customParse("18-Aug-2010");
// "Wed Aug 18 2010 00:00:00"
customParse("19-Aug-2010") > customParse("18-Aug-2010");
// true
You can do the parsing manually, for your given format, but I'd suggest you use the date.js library to parse the dates to Date objects and then compare.
Check it out, its awesome!
And moreover, its a great addition to your js utility toolbox.
The native Date can parse "MMM+ dd yyyy", which gives:
function parseDMY(s){
return new Date(s.replace(/^(\d+)\W+(\w+)\W+/, '$2 $1 '));
}
+parseDMY('19-August-2010') == +new Date(2010, 7, 19) // true
parseDMY('18-Aug-2010') < parseDMY('19-Aug-2010') // true
Firstly, the 'dd-MMM-yyyy' format isn't an accepted input format of the Date constructor (it returns an "invalid date" object) so we need to parse this ourselves. Let's write a function to return a Date object from a string in this format.
function parseMyDate(s) {
var m = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
var match = s.match(/(\d+)-([^.]+)-(\d+)/);
var date = match[1];
var monthText = match[2];
var year = match[3];
var month = m.indexOf(monthText.toLowerCase());
return new Date(year, month, date);
}
Date objects implicitly typecast to a number (milliseconds since 1970; epoch time) so you can compare using normal comparison operators:
if (parseMyDate(date1) > parseMyDate(date2)) ...
Update: IE10, FX30 (and likely more) will understand "18 Aug 2010" without the dashes - Chrome handles either
so Date.parse("18-Aug-2010".replace("/-/g," ")) works in these browsers (and more)
Live Demo
Hence
function compareDates(str1,str2) {
var d1 = Date.parse(str1.replace("/-/g," ")),
d2 = Date.parse(str2.replace("/-/g," "));
return d1<d2;
}