I'm trying to check the users input field to see if it is in the future and if it is in dd/mm/yyyy format but I have no idea why the format part of my code doesn't fire at all! In fact nothing seems to be working on Jsfiddle but at least my "check date in the future" function works locally.
I don't know the correct way of going about this.
to explain this, I've created this FIDDLE
And this is my full javascript code. I need to stay with pure javascript by the way:
function checkdate(){
//var sendDate = document.getElementById('send_year').value + '/' + document.getElementById('send_month').value + '/' + document.getElementById('send_day').value;
var sendDate = document.getElementById('returning_date').value;
sendDate = new Date(Date.parse(sendDate.replace(/-/g,' ')))
today = new Date();
today.setHours(0,0,0,0)
if (sendDate < today) {
//alert('The date can\'t be in the past. Please pick another date.');
document.getElementById('error8').innerHTML = 'The date can\'t be in the past. Please pick another date.';
return false;
}
else
{
document.getElementById('error8').innerHTML = '';
}
if(sendDate.match(/^[0-9]{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/))
{
alert('works out');
}
}
could someone please advise on this issue?
Thanks in advance.
One problem is that you are trying to run sendDate.match, but sendDate has been converted into a Date object so it does not have a match method.
You should run your regular expression before you convert it to a Date, in validation, you typically check that the input conforms to a format before you run further validation like range validation.
Date strings should always be manually parsed, you should never allow the Date constructor or Date.parse to parse strings (the Date constructor parses strings in exactly the same way Date.parse does).
To parse and validate a date string is fairly straight forward, just parse the string and see if you get a valid date:
/* Parse a string in d/m/y format. Separator can be any non–digit
** Avoid conversion of two digit dates to 20th century
** Returns an invalid Date if string is not a valid date (per ECMA-262)
**
** #param {string} s - Date string to parse
** #returns {Date}
*/
function parseDMY(s) {
var b = s.split(/\D/);
var d = new Date();
d.setHours(0,0,0,0);
d.setFullYear(b[2], --b[1], b[0]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
// Test valid date
document.write(parseDMY('23/01/2016'));
// Test invalid date
document.write('<br>' + parseDMY('35/12/2016'));
Note that this will accept a date like 1/5/16 and treat is as 1 May, 0016. If you want to guarantee that the day and month values have two digits and the year for, then add:
/^\d\d\D\d\d\D\d{4}$/.test(s)
to the validation test at the end. However, I don't like forcing 2 digits for day and month as people don't usually write dates as "01/08/2016", they use "1/8/2016".
First of all, the function needs to be wrapped in <head> (hit the cog in the js tab), otherwise the function can't be found.
But your main problem is that you are using European style of date formatting, so you'll get a "Invalid Date" exception when creating the date. Refer to this question on how to convert it to USA-style and make it available for the Date object (check the reference for all possible uses)
My proposal is:
Date.prototype.fromString = function(str) {
var m = str.match(/([0-9]{2})(-|\/)([0-9]{2})(-|\/)([0-9]{4})/);
if (m == null) {
return null;
}
for (var i = 0; i < m.length; i++) {
if (typeof(m[i]) === 'undefined') {
return null;
};
};
var year = parseInt(m[5]);
var month = parseInt(m[1]) - 1;
var day = parseInt(m[3]);
if (month == 0 || day == 0) {
return null;
}
return new Date(year, month, day);
}
function checkdate(e, obj, errMsgSel){
var sendDate =obj.value;
sendDate = (new Date()).fromString(sendDate);
if (sendDate == null) {
if (e.type == 'blur') {
obj.value = '';
}
return;
}
today = new Date();
today.setHours(0,0,0,0)
if (sendDate < today) {
//alert('The date can\'t be in the past. Please pick another date.');
document.getElementById(errMsgSel).innerHTML = 'The date can\'t be in the past. Please pick another date.';
return false;
}
else
{
document.getElementById(errMsgSel).innerHTML = '';
}
} $(function () {
});
<input onblur="checkdate(event, this, 'error8');" onKeyUp="checkdate(event, this, 'error8');" type='text' name="text1" placeholder='dd/mm/yyyy' id='returning_date'>
<span id='error8' style='color:red;'>format</span> <br><Br>
I'd like to tell the difference between valid and invalid date objects in JS, but couldn't figure out how:
var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'
Any ideas for writing an isValidDate function?
Ash recommended Date.parse for parsing date strings, which gives an authoritative way to check if the date string is valid.
What I would prefer, if possible, is have my API accept a Date instance and to be able to check/assert whether it's valid or not. Borgar's solution does that, but I need to test it across browsers. I also wonder whether there's a more elegant way.
Ash made me consider not having my API accept Date instances at all, this would be easiest to validate.
Borgar suggested testing for a Date instance, and then testing for the Date's time value. If the date is invalid, the time value is NaN. I checked with ECMA-262 and this behavior is in the standard, which is exactly what I'm looking for.
Here's how I would do it:
if (Object.prototype.toString.call(d) === "[object Date]") {
// it is a date
if (isNaN(d)) { // d.getTime() or d.valueOf() will also work
// date object is not valid
} else {
// date object is valid
}
} else {
// not a date object
}
Update [2018-05-31]: If you are not concerned with Date objects from other JS contexts (external windows, frames, or iframes), this simpler form may be preferred:
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
Update [2021-02-01]: Please note that there is a fundamental difference between "invalid dates" (2013-13-32) and "invalid date objects" (new Date('foo')). This answer does not deal with validating date input, only if a Date instance is valid.
Instead of using new Date() you should use:
var timestamp = Date.parse('foo');
if (isNaN(timestamp) == false) {
var d = new Date(timestamp);
}
Date.parse() returns a timestamp, an integer representing the number of milliseconds since 01/Jan/1970. It will return NaN if it cannot parse the supplied date string.
You can check the validity of a Date object d via
d instanceof Date && isFinite(d)
To avoid cross-frame issues, one could replace the instanceof check with
Object.prototype.toString.call(d) === '[object Date]'
A call to getTime() as in Borgar's answer is unnecessary as isNaN() and isFinite() both implicitly convert to number.
shortest answer to check valid date
if(!isNaN(date.getTime()))
My solution is for simply checking whether you get a valid date object:
Implementation
Date.prototype.isValid = function () {
// An invalid date object returns NaN for getTime() and NaN is the only
// object not strictly equal to itself.
return this.getTime() === this.getTime();
};
Usage
var d = new Date("lol");
console.log(d.isValid()); // false
d = new Date("2012/09/11");
console.log(d.isValid()); // true
I have seen some answers that came real close to this little snippet.
JavaScript way:
function isValidDate(dateObject){
return new Date(dateObject).toString() !== 'Invalid Date';
}
console.log(isValidDate('WTH')); // -> false
console.log(isValidDate(new Date('WTH'))); // -> false
console.log(isValidDate(new Date())); // -> true
ES2015 way:
const isValidDate = dateObject => new Date(dateObject)
.toString() !== 'Invalid Date';
console.log(isValidDate('WTH')); // -> false
console.log(isValidDate(new Date('WTH'))); // -> false
console.log(isValidDate(new Date())); // -> true
You can simply use moment.js
Here is an example:
var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false
The validation section in the documentation is quite clear.
And also, the following parsing flags result in an invalid date:
overflow: An overflow of a date field, such as a 13th month, a 32nd day of the month (or a 29th of February on non-leap years), a 367th day of the year, etc. overflow contains the index of the invalid unit to match #invalidAt (see below); -1 means no overflow.
invalidMonth: An invalid month name, such as moment('Marbruary', 'MMMM');. Contains the invalid month string itself, or else null.
empty: An input string that contains nothing parsable, such as moment('this is nonsense');. Boolean.
Etc.
Source: http://momentjs.com/docs/
Would like to mention that the jQuery UI DatePicker widget has a very good date validator utility method that checks for format and validity (e.g., no 01/33/2013 dates allowed).
Even if you don't want to use the datepicker widget on your page as a UI element, you can always add its .js library to your page and then call the validator method, passing the value you want to validate into it. To make life even easier, it takes a string as input, not a JavaScript Date object.
See: http://api.jqueryui.com/datepicker/
It's not listed as a method, but it is there-- as a utility function. Search the page for "parsedate" and you'll find:
$.datepicker.parseDate( format, value, settings ) - Extract a date from a string value with a specified format.
Example usage:
var stringval = '01/03/2012';
var testdate;
try {
testdate = $.datepicker.parseDate('mm/dd/yy', stringval);
// Notice 'yy' indicates a 4-digit year value
} catch (e)
{
alert(stringval + ' is not valid. Format must be MM/DD/YYYY ' +
'and the date value must be valid for the calendar.';
}
(More info re specifying date formats is found at http://api.jqueryui.com/datepicker/#utility-parseDate)
In the above example, you wouldn't see the alert message since '01/03/2012' is a calendar-valid date in the specified format. However if you made 'stringval' equal to '13/04/2013', for example, you would get the alert message, since the value '13/04/2013' is not calendar-valid.
If a passed-in string value is successfully parsed, the value of 'testdate' would be a Javascript Date object representing the passed-in string value. If not, it'd be undefined.
After reading every answer so far, I am going to offer the most simple of answers.
Every solution here mentions calling date.getTime(). However, this is not needed, as the default conversion from Date to Number is to use the getTime() value. Yep, your type checking will complain. :) And the OP cleary knows they have a Date object, so no need to test for that either.
To test for an invalid date:
isNaN(date)
To test for a valid date:
!isNaN(date)
or (thanks to icc97 for this alternative)
isFinite(date)
or typescript (thanks to pat-migliaccio)
isFinite(+date)
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());
I really liked Christoph's approach (but didn't have enough of a reputation to vote it up).
For my use, I know I will always have a Date object so I just extended date with a valid() method.
Date.prototype.valid = function() {
return isFinite(this);
}
Now I can just write this and it's much more descriptive than just checking isFinite in code...
d = new Date(userDate);
if (d.valid()) { /* do stuff */ }
I use the following code to validate values for year, month and date.
function createDate(year, month, _date) {
var d = new Date(year, month, _date);
if (d.getFullYear() != year
|| d.getMonth() != month
|| d.getDate() != _date) {
throw "invalid date";
}
return d;
}
For details, refer to Check date in javascript
you can check the valid format of txDate.value with this scirpt. if it was in incorrect format the Date obejct not instanced and return null to dt .
var dt = new Date(txtDate.value)
if (isNaN(dt))
And as #MiF's suggested in short way
if(isNaN(new Date(...)))
Too many complicated answers here already, but a simple line is sufficient (ES5):
Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;
or even in ES6 :
Date.prototype.isValid = d => !isNaN(Date.parse(d));
Why am I writing a 48th answer after so many have tried before me? Most of the answers are partly correct and will not work in every situation, while others are unnecessarily verbose and complex. Below is a very concise solution. This will checking if it is Date type and then check if a valid date object:
return x instanceof Date && !!x.getDate();
Now for parsing date Text: Most of the solutions use Date.parse(), or "new Date()" -- both of these will fail certain situations and can be dangerous. JavaScript parses a wide variety of formats and also is dependent on localization. For example, strings like "1" and "blah-123" will parse as a valid date.
Then there are posts that either use a ton of code, or a mile-long RegEx, or use third party frameworks.
This is dead simple method to validate a date string.
function isDate(txt) {
var matches = txt.match(/^\d?\d\/(\d?\d)\/\d{4}$/); //Note: "Day" in the RegEx is parenthesized
return !!matches && !!Date.parse(txt) && new Date(txt).getDate()==matches[1];
}
TEST THE FUNCTION
<br /><br />
<input id="dt" value = "12/21/2020">
<input type="button" value="validate" id="btnAction" onclick="document.getElementById('rslt').innerText = isDate(document.getElementById('dt').value)">
<br /><br />
Result: <span id="rslt"></span>
The first line of isDate parses the input text with a simple RegEx to validate for date formats mm/dd/yyyy, or m/d/yyyy. For other formats, you will need to change the RegEx accordingly, e.g. for dd-mm-yyyy the RegEx becomes /^(\d?\d)-\d?\d-\d{4}$/
If parse fails, "matches" is null, otherwise it stores the day-of-month. The second lines does more tests to ensure it is valid date and eliminates cases like 9/31/2021 (which JavaScript permits). Finally note the double-whack (!!) converts "falsy" to a boolean false.
This just worked for me
new Date('foo') == 'Invalid Date'; //is true
However this didn't work
new Date('foo') === 'Invalid Date'; //is false
None of these answers worked for me (tested in Safari 6.0) when trying to validate a date such as 2/31/2012, however, they work fine when trying any date greater than 31.
So I had to brute force a little. Assuming the date is in the format mm/dd/yyyy. I am using #broox answer:
Date.prototype.valid = function() {
return isFinite(this);
}
function validStringDate(value){
var d = new Date(value);
return d.valid() && value.split('/')[0] == (d.getMonth()+1);
}
validStringDate("2/29/2012"); // true (leap year)
validStringDate("2/29/2013"); // false
validStringDate("2/30/2012"); // false
For Angular.js projects you can use:
angular.isDate(myDate);
I wrote the following solution based on Borgar's solution. Included in my library of auxiliary functions, now it looks like this:
Object.isDate = function(obj) {
/// <summary>
/// Determines if the passed object is an instance of Date.
/// </summary>
/// <param name="obj">The object to test.</param>
return Object.prototype.toString.call(obj) === '[object Date]';
}
Object.isValidDate = function(obj) {
/// <summary>
/// Determines if the passed object is a Date object, containing an actual date.
/// </summary>
/// <param name="obj">The object to test.</param>
return Object.isDate(obj) && !isNaN(obj.getTime());
}
I rarely recommend libraries when one can do without. But considering the plethora of answers so far it seems worth pointing out that the popular library "date-fns" has a function isValid. The following documentation is taken from their website:
isValid argument
Before v2.0.0
v2.0.0 onward
new Date()
true
true
new Date('2016-01-01')
true
true
new Date('')
false
false
new Date(1488370835081)
true
true
new Date(NaN)
false
false
'2016-01-01'
TypeError
false
''
TypeError
false
1488370835081
TypeError
true
NaN
TypeError
false
Date.prototype.toISOString throws RangeError (at least in Chromium and Firefox) on invalid dates. You can use it as a means of validation and may not need isValidDate as such (EAFP). Otherwise it's:
function isValidDate(d)
{
try
{
d.toISOString();
return true;
}
catch(ex)
{
return false;
}
}
IsValidDate: function(date) {
var regex = /\d{1,2}\/\d{1,2}\/\d{4}/;
if (!regex.test(date)) return false;
var day = Number(date.split("/")[1]);
date = new Date(date);
if (date && date.getDate() != day) return false;
return true;
}
I've written this function. Pass it a string parameter and it will determine whether it's a valid date or not based on this format "dd/MM/yyyy".
here is a test
input: "hahaha",output: false.
input: "29/2/2000",output: true.
input: "29/2/2001",output: false.
function isValidDate(str) {
var parts = str.split('/');
if (parts.length < 3)
return false;
else {
var day = parseInt(parts[0]);
var month = parseInt(parts[1]);
var year = parseInt(parts[2]);
if (isNaN(day) || isNaN(month) || isNaN(year)) {
return false;
}
if (day < 1 || year < 1)
return false;
if(month>12||month<1)
return false;
if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)
return false;
if ((month == 4 || month == 6 || month == 9 || month == 11 ) && day > 30)
return false;
if (month == 2) {
if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0 && (year % 100) == 0)) {
if (day > 29)
return false;
} else {
if (day > 28)
return false;
}
}
return true;
}
}
None of the above solutions worked for me what did work however is
function validDate (d) {
var date = new Date(d);
var day = "" + date.getDate();
if ( day.length == 1 ) day = "0" + day;
var month = "" + (date.getMonth() + 1);
if ( month.length == 1 ) month = "0" + month;
var year = "" + date.getFullYear();
return (( month + "/" + day + "/" + year ) == d );
}
the code above will see when JS makes 02/31/2012 into 03/02/2012 that it's not valid
Date object to string is more simple and reliable way to detect if both fields are valid date.
e.g. If you enter this "-------" to the date input field. Some of the above answers won't work.
jQuery.validator.addMethod("greaterThan",
function(value, element, params) {
var startDate = new Date($(params).val());
var endDate = new Date(value);
if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {
return false;
} else {
return endDate > startDate;
}
},'Must be greater than {0}.');
you can convert your date and time to milliseconds getTime()
this getTime() Method return Not a Number NaN when not valid
if(!isNaN(new Date("2012/25/255").getTime()))
return 'valid date time';
return 'Not a valid date time';
I combined the best performance results I found around that check if a given object:
is a Date instance (benchmark here)
has a valid date (benchmark here)
The result is the following:
function isValidDate(input) {
if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
return false;
var time = input.getTime();
return time === time;
};
A ready function based on top rated answer:
/**
* Check if date exists and is valid.
*
* #param {String} dateString Date in YYYY-mm-dd format.
*/
function isValidDate(dateString) {
var isValid = false;
var date;
date =
new Date(
dateString);
if (
Object.prototype.toString.call(
date) === "[object Date]") {
if (isNaN(date.getTime())) {
// Date is unreal.
} else {
// Date is real if month and day match each other in date and string (otherwise may be shifted):
isValid =
date.getUTCMonth() + 1 === dateString.split("-")[1] * 1 &&
date.getUTCDate() === dateString.split("-")[2] * 1;
}
} else {
// It's not a date.
}
return isValid;
}
No one has mentioned it yet, so Symbols would also be a way to go:
Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date") // true
Symbol.for(new Date()) === Symbol.for("Invalid Date") // false
console.log('Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")', Symbol.for(new Date("Peter")) === Symbol.for("Invalid Date")) // true
console.log('Symbol.for(new Date()) === Symbol.for("Invalid Date")', Symbol.for(new Date()) === Symbol.for("Invalid Date")) // false
Be aware of:
https://caniuse.com/#search=Symbol
Inspired by Borgar's approach I made sure that the code not only validates the date, but actually makes sure the date is a real date, meaning that dates like 31/09/2011 and 29/02/2011 are not allowed.
function(dateStr) {
s = dateStr.split('/');
d = new Date(+s[2], s[1] - 1, +s[0]);
if (Object.prototype.toString.call(d) === "[object Date]") {
if (!isNaN(d.getTime()) && d.getDate() == s[0] &&
d.getMonth() == (s[1] - 1)) {
return true;
}
}
return "Invalid date!";
}
I have got below java script code that will validates date range ... when the user entered the today date or any future dates I have set IsValid to true and then will do the save operation ....
for that purpose I have written below code ..
function Save(e) {
var popupNotification = $("#popupNotification").data("kendoNotification");
var container = e.container;
var model = e.model;
var isValid = true;
var compareDate = e.model.DeliveryDate;
alert(compareDate);
var todayDate = new Date();
var compareDateModified = new Date(compareDate)
alert(compareDateModified);
if (compareDateModified > todayDate || compareDateModified === todayDate) {
isValid = true;
}
else
isValid = false;
e.preventDefault();
if (isValid == false)
{
popupNotification.show("Delivery Date should be today date or Greater", "error");
}
$('#Previous').show();
$('#Next').show();
}
Its working fine when I give the future dates but its not working for today date. I also need to check the today's date. I am not able to figure it out the error alert when I try to enter to the today date .
You are comparing two objects of the same type, but different objects, so that will always result in 'unequal'
If you use date.getTime() you will get better results in your comparison - but only if the time component is the same of course.
Think of the Date object like a timestamp. It is based on the unix-style of timestamps (the amount of seconds since 1st January, 1970) so the Date object isn't the day, it is the Date AND the Time.
What you're comparing is the times as well, which could get a little iffy. If only days matter, try using:
fullCompareDate = compareDateModified.getFullYear() + "/" + compareDateModified.getMonth() + "/" + compareDateModified.getDate();
fullTodayDate= todayDate.getFullYear() + "/" + todayDate.getMonth() + "/" + todayDate.getDate();
if(compareDateModified>todayDate||fullCompareDate==fullTodayDate)
{
//Do something
}
This will compare the date and time to make sure they are greater OR check the current date with the compare date (as strings)
Another solution is to blank out the times on both dates:
compareDateModified.setHours(0,0,0,0);
todayDate.setHours(0,0,0,0);
if(compareDateModified>=todayDate)
{
//Do something
}
You are comparing the compareDateModified to todayDate on the millisecond level. To compare at the day level:
var todayDate = new Date();
todayDate.setHours(0,0,0,0);
//you may also have to truncate the compareDateModified to the first
//second of the day depending on how you setup compareDate
if (compareDateModified >= todayDate) {
isValid = true;
}
Seems to be a simple and commonly asked question but after googling for a while havent come up with an answer.
Very simply, I have two variables each with a datetime value in format yyyy-mm-dd hh:mm
I want to compare which is bigger and perform logic accordingly:
example: here
var fromDate = '2014-02-14 07:00';
var toDate = '2014-02-14 07:00';
if (Date.parse(fromDate) > Date.parse(toDate)) {
alert("Invalid Date Range!\nStart Date cannot be after End Date!")
} else {
alert("VALID Date Range!\n Start Date is before End");
}
The above continuously returns the successful validation.
Any advice, suggestions? examples? Thanks,
It happens that the format you're using can be compared lexigraphically. So no parsing required:
var fromDate = '2014-02-14 07:00';
var toDate = '2014-02-14 07:00';
if (fromDate > toDate) {
alert("Invalid Date Range!\nStart Date cannot be after End Date!");
} else {
alert("VALID Date Range!\n Start Date is before End");
}
This is because the most significant fields precede the less significant fields, throughout the string.
But if you really want date/time values, that string format isn't directly supported by the specification. You have three choices:
Use a library like MomentJS.
Massage the string so that it's in a supported format, but be aware that until ES5, there was no standard format dictated by the spec.
Do it yourself
The latter looks something like this:
function parseMyDate(str) {
var parts = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/.exec(str);
if (!parts) {
return null;
}
return new Date(parseInt(parts[1], 10), // Year
parseInt(parts[2], 10) - 1), // Month
parseInt(parts[3], 10), // Day
parseInt(parts[4], 10), // Hours
parseInt(parts[5], 10)); // Minutes
}
Then use parseMyDate where you have Date.parse above.
this is real ugly but serves the purpose...
var fromDate = '2014-02-27 09:00';
fromDate=fromDate.replace("-", "/");
fromDate=fromDate.replace("-", "/");
var toDate = '2014-02-27 10:00';
toDate=toDate.replace("-", "/");
toDate=toDate.replace("-", "/");
var fromDate=(new Date(fromDate).getTime()/1000);
var toDate=(new Date(toDate).getTime()/1000);
if(fromDate>toDate){
alert('CORRECT');
} else {
alert('INCORRECT, from after to');
}