IF safety check around object method call [duplicate] - javascript

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!";
}

Related

What is an elegant way to check if a date is valid in JavaScript? [duplicate]

What is an easy way to check if a value is a valid date, any known date format allowed.
For example I have the values 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000 which should all be recognized as date values, and the values 200, 10, 350, which should not be recognized as a date value. What is the simplest way to check this, if this is even possible? Because timestamps would also be allowed.
2015 Update
It is an old question but other new questions like:
How to validate if a string is a valid date in js
get closed as duplicates of this one, so I think it's important to add some fresh info here. I'm writing it because I got scared thinking that people actually copy and paste some of the code posted here and use it in production.
Most of the answers here either use some complex regular expressions that match only some very specific formats and actually do it incorrectly (like matching January 32nd while not matching actual ISO date as advertised - see demo) or they try to pass anything to the Date constructor and wish for the best.
Using Moment
As I explained in this answer there is currently a library available for that:
Moment.js
It is a library to parse, validate, manipulate, and display dates in JavaScript, that has a much richer API than the standard JavaScript date handling functions.
It is 12kB minified/gzipped and works in Node.js and other places:
bower install moment --save # bower
npm install moment --save # npm
Install-Package Moment.js # NuGet
spm install moment --save # spm
meteor add momentjs:moment # meteor
Using Moment you can be very specific about checking valid dates. Sometimes it is very important to add some clues about the format that you expect. For example, a date such as 06/22/2015 looks like a valid date, unless you use a format DD/MM/YYYY in which case this date should be rejected as invalid. There are few ways how you can tell Moment what format you expect, for example:
moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false
The true argument is there so the Moment won't try to parse the input if it doesn't exactly conform to one of the formats provided (it should be a default behavior in my opinion).
You can use an internally provided format:
moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true
And you can use multiple formats as an array:
var formats = [
moment.ISO_8601,
"MM/DD/YYYY :) HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015 :) 13*17*21", formats, true).isValid(); // true
moment("06/22/2015 :( 13*17*21", formats, true).isValid(); // false
See: DEMO.
Other libraries
If you don't want to use Moment.js, there are also other libraries:
XDate
DateJS
2016 Update
I created the immoment module that is like (a subset of) Moment but without surprises caused by mutation of existing objects (see the docs for more info).
2018 Update
Today I recommend using Luxon for date/time manipulation instead of Moment, which (unlike Moment) makes all object immutable so there are no nasty surprises related to implicit mutation of dates.
More info
See also:
Managing Dates and Times Using Moment.js by Jay Raj
Working with JavaScript Dates Using Moment.js by Bradley Holbrook
A series of articles by Rob Gravelle on JavaScript date parsing libraries:
A Roundup of Popular JavaScript Date Parsing Libraries: Moment.js
A Roundup of Popular JavaScript Date Parsing Libraries: Datejs
A Roundup of Popular JavaScript Date Parsing Libraries: XDate
Bottom line
Of course anyone can try to reinvent the wheel, write a regular expression (but please actually read ISO 8601 and RFC 3339 before you do it) or call buit-in constructors with random data to parse error messages like 'Invalid Date' (Are you sure this message is exactly the same on all platforms? In all locales? In the future?) or you can use a tested solution and use your time to improve it, not reinvent it. All of the libraries listed here are open source, free software.
This is how I solved this problem in an app I'm working on right now:
updated based on feedback from krillgar:
var isDate = function(date) {
return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Would Date.parse() suffice?
See its relative MDN Documentation page.
Date.parse returns a timestamp if string date is valid. Here are some use cases:
// /!\ from now (2021) date interpretation changes a lot depending on the browser
Date.parse('01 Jan 1901 00:00:00 GMT') // -2177452800000
Date.parse('01/01/2012') // 1325372400000
Date.parse('153') // NaN (firefox) -57338928561000 (chrome)
Date.parse('string') // NaN
Date.parse(1) // NaN (firefox) 978303600000 (chrome)
Date.parse(1000) // -30610224000000 from 1000 it seems to be treated as year
Date.parse(1000, 12, 12) // -30610224000000 but days and month are not taken in account like in new Date(year, month,day...)
Date.parse(new Date(1970, 1, 0)) // 2588400000
// update with edge cases from comments
Date.parse('4.3') // NaN (firefox) 986248800000 (chrome)
Date.parse('2013-02-31') // NaN (firefox) 1362268800000 (chrome)
Date.parse("My Name 8") // NaN (firefox) 996616800000 (chrome)
new Date(date) === 'Invalid Date' only works in Firefox and Chrome. IE8 (the one I have on my machine for testing purposes) gives NaN.
As was stated to the accepted answer, Date.parse(date) will also work for numbers. So to get around that, you could also check that it is not a number (if that's something you want to confirm).
var parsedDate = Date.parse(date);
// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
/* do your work */
}
Does not work consistently, watch out!
isDate('Leyweg 1') returns true on Chrome (Firefox returns false) 🤔
Read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse (Date.parse is called under the hood when invoking like so: new Date(someDateString).
Original answer:
function isDate(dateStr) {
return !isNaN(new Date(dateStr).getDate());
}
This will work on any browser since it does not rely on "Invalid Date" check.
This will work with legacy code before ES6.
This will work without any library.
This will work regardless of any date format.
This does not rely on Date.parse which fails the purpose when values like "Spiderman 22" are in date string.
This does not ask us to write any RegEx.
None of the answers here address checking whether the date is invalid such as February 31. This function addresses that by checking if the returned month is equivalent to the original month and making sure a valid year was presented.
//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
var separators = ['\\.', '\\-', '\\/'];
var bits = s.split(new RegExp(separators.join('|'), 'g'));
var d = new Date(bits[2], bits[1] - 1, bits[0]);
return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
}
How about something like this? It will test if it is a Date object or a date string:
function isDate(value) {
var dateFormat;
if (toString.call(value) === '[object Date]') {
return true;
}
if (typeof value.replace === 'function') {
value.replace(/^\s+|\s+$/gm, '');
}
dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
return dateFormat.test(value);
}
I should mention that this doesn't test for ISO formatted strings but with a little more work to the RegExp you should be good.
Use Regular expression to validate it.
isDate('2018-08-01T18:30:00.000Z');
isDate(_date){
const _regExp = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
return _regExp.test(_date);
}
By referring to all of the above comments, I have come to a solution.
This works if the Date passed is in ISO format or need to manipulate for other formats.
var isISO = "2018-08-01T18:30:00.000Z";
if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
if(isISO == new Date(isISO).toISOString()) {
console.log("Valid date");
} else {
console.log("Invalid date");
}
} else {
console.log("Invalid date");
}
You can play here on JSFiddle.
Here is an improved function that uses only Date.parse():
function isDate(dateToTest) {
return isNaN(dateToTest) && !isNaN(Date.parse(dateToTest)));
}
Note: Date.parse() will parse numbers: for example Date.parse(1) will return a date. So here we check if dateToTest is not a number then if it is a date.
I know it's an old question but I faced the same problem and saw that none of the answers worked properly - specifically weeding out numbers (1,200,345,etc..) from dates, which is the original question. Here is a rather unorthodox method I could think of and it seems to work. Please point out if there are cases where it will fail.
if(sDate.toString() == parseInt(sDate).toString()) return false;
This is the line to weed out numbers. Thus, the entire function could look like:
function isDate(sDate) {
if(sDate.toString() == parseInt(sDate).toString()) return false;
var tryDate = new Date(sDate);
return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");
}
console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));
I feel none of the answers correctly understood what the OP asked. The issue here is that JavaScript can parse any number as a valid date, since the Date object can parse a string like '3000' as the year and will return a valid Date instance:
new Date('3000')
> Wed Jan 01 3000 02:00:00 GMT+0200 (Eastern European Standard Time)
To solve this, we can use the Day.js library's parsing method in strict mode by passing in a third argument. It's documented in their String + Format page. In order for parsing to work based on a format, we must also enable the CustomParseFormat plugin. I'm assuming you can use ESM imports here or have a compiler like Webpack set up
import dayjs from 'dayjs'
import formatParser from 'dayjs/plugin/customParseFormat'
dayjs.extend(formatParser)
dayjs('3000', 'YYYY-MM-DD', true).isValid()
> false
I would do this
var myDateStr= new Date("2015/5/2");
if( ! isNaN ( myDateStr.getMonth() )) {
console.log("Valid date");
}
else {
console.log("Invalid date");
}
Play here
is it fine to check for a Date related function is available for the object to find whether it is a Date object or not ?
like
var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;
This callable function works perfectly, returns true for valid date.
Be sure to call using a date on ISO format (yyyy-mm-dd or yyyy/mm/dd):
function validateDate(isoDate) {
if (isNaN(Date.parse(isoDate))) {
return false;
} else {
if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
return false;
}
}
return true;
}
I think the most straight forward solution would be
Date.parse(yourDate) > 0 ? true : false;
If it is not a valid date, it will be NaN, which is not greater than 0.
Here's a minimalist version.
var isDate = function (date) {
return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
Ok, this is an old question, but I found another solution while checking the solutions here. For me works to check if the function getTime() is present at the date object:
const checkDate = new Date(dateString);
if (typeof checkDate.getTime !== 'function') {
return;
}
i find this solution very good:
const DateTime = require('luxon').DateTime;
isDateValid(stringDate) {
let date = DateTime.fromFormat(stringDate, 'd-M-y');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'd,M,y');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'y-M-d');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'y,M,d');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'y.M.d');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'd.M.y');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'y/M/d');
if (date.invalid === null) {
return date.toJSDate();
}
date = DateTime.fromFormat(stringDate, 'd/M/y');
if (date.invalid === null) {
return date.toJSDate();
}
return false;
}
isDateValid('30.12.86'); //true
isDateValid('30/12/86'); //true
isDateValid('86-12-40'); //false
and you can easily add more formats
I believe this is the simplest working answer for date that contains only numbers:
var rst = Date.parse(sDate.replaceAll(" ",""));
if(rst===NaN) console.log("not a date");
else console.log("a great date")
By removing spaces you detect values like "hello 2" that are taken as a date.
For the dates that contain strings like day name or month name ... I believe it is about string validation.
This is how I end up doing it. This will not cover all formats.
You have to adjust accordingly. I have control on the format, so it works for me
function isValidDate(s) {
var dt = "";
var bits = [];
if (s && s.length >= 6) {
if (s.indexOf("/") > -1) {
bits = s.split("/");
}
else if (s.indexOf("-") > -1) {
bits = s.split("-");
}
else if (s.indexOf(".") > -1) {
bits = s.split(".");
}
try {
dt = new Date(bits[2], bits[0] - 1, bits[1]);
} catch (e) {
return false;
}
return (dt.getMonth() + 1) === parseInt(bits[0]);
} else {
return false;
}
}
This function verifies that the input string in the format m/d/yyyy or mm/dd/yyyy can be converted to a date and that the date is a valid date matching the input string. Add more conditional checks to verify additional formats.
/**
* Verify if a string is a date
* #param {string} sDate - string that should be formatted m/d/yyyy or mm/dd/yyyy
* #return {boolean} whether string is a valid date
*/
function isValidDate(sDate) {
let newDate = new Date(sDate);
console.log(sDate + " date conversion: " + newDate);
let isDate = (!isNaN(newDate.getTime()));
console.log(sDate + " is a date: " + isDate);
if (isDate) {
let firstSlash = sDate.indexOf("/");
let secondSlash = sDate.indexOf("/",firstSlash+1);
let originalDateString = parseInt(sDate.slice(0,firstSlash),10) + "/" + parseInt(sDate.slice(firstSlash+1,secondSlash),10) + "/" + parseInt(sDate.slice(secondSlash+1),10);
let newDateString = (newDate.getMonth()+1) + "/" + (newDate.getDate()) + "/" + (newDate.getFullYear());
isDate = (originalDateString == newDateString);
console.log(originalDateString + " matches " + newDateString + ": " + isDate);
}
return isDate;
}
Here is what one could use to validate that the input is a number or a string that can be converted to a date object.
It covers the following cases:
catching whatever input leads to "Invalid Date" date constructor result;
catching the cases where the date is "valid" from technical point of view, but it is not valid from business logic point of view, like
new Date(null).getTime(): 0
new Date(true).getTime(): 1
new Date(-3.14).getTime(): -3
new Date(["1", "2"]).toDateString(): Tue Jan 02 2001
new Date([1, 2]).toDateString(): Tue Jan 02 2001
function checkDateInputValidity(input, lowerLimit, upperLimit) {
// make sure the input is a number or string to avoid false positive correct dates:
if (...) {
return false
}
// create the date object:
const date = new Date(input)
// check if the Date constructor failed:
if (date.toDateString() === 'Invalid Date') {
return false
}
// check if the Date constructor succeeded, but the result is out of range:
if (date < new Date(lowerLimit) || date > new Date(upperLimit)) {
return false
}
return true
}
// const low = '2021-12-31T23:59:59'
// const high = '2025-01-01T00:00:00'

Javascript Date allows invalid data (e.g. Feb 30th) [duplicate]

This question already has answers here:
How to validate a date?
(11 answers)
Closed 6 years ago.
How to validate a date? I mean not the format, but the logic.
For example: Feb 30th is not a valid date.
var date = new Date("2015-02-29T13:02:49.073Z"); // 2015 Feb 29th does not exist
console.log(date.toISOString());
Returns 2015-03-01T13:02:49.073Z (March 1st).
But I want a information that this date (input) is not valid.
Edit:
Tested in Chrome. Firefox returns "invalid date". But not on parsing.
Only when the date is used (e.g. toISOString()) an exception is thrown.
try
{
var date = new Date("2015-02-29T13:02:49.073Z");
console.log(date.toISOString());
}
catch(e)
{
console.log("error: " + e.message);
}
Firefox:
invalid date
Chrome:
(nothing, just switched to the next date.)
Summary: It is browser-dependent. So, not recommended to use.
jsfiddle example
I use this function to check whether a date is valid or not:
function isValidDate(year, month, day) {
month = month - 1;
var d = new Date(year, month, day);
if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) {
return true;
}
return false;
}
The easiest thing I can think of, is to convert the parsed date to ISO string and compare it to the original input:
var input = "2015-02-29T13:02:49.073Z"
var date = new Date(input);
var isValid = (input === date.toISOString());
I wrote small function for you:
function check_date(str){
try{
return str == new Date(str).toISOString()
}catch(e){
return false;
}
}
Try this
console.log(check_date('2015-02-01T13:02:49.073Z'));
console.log(check_date('2015-02-35T13:02:49.073Z'));
console.log(check_date('2015-02-29T13:02:49.073Z'));
https://jsfiddle.net/8o040ctr/
I've found that behavior rather amusing. I used to just convert the input to a date (as you've done), then update the text in the textbox to show the date as interpreted by JavaScript so the user would see the resulting (valid) date.
Luckily, we can do much better now. Moment.js is a fantastic library for dealing with date/time values in JavaScript. It's sure made life a lot easier for me!
http://momentjs.com/
If you pass a string that starts with 'YYYY-MM' format, like you have in the question, you could use this function:
function makeDate(s) {
var date = new Date(s);
if (date.toISOString(date).substr(0,7) != s.substr(0,7)) throw "Invalid date";
return date;
}
dt = makeDate('2015-02-29T13:02:49.073Z');
This makeDate function would replace the plain new Date(...) call, but will also throw an error in Chrome when it is passed an invalid date string.
Dates in browsers are always very tricky, I suggest you to use a js lib like moment: http://momentjs.com/
then you can use .isValid() method for ex.:
moment('03:55', 'HH:mm').isValid();
moment('2012-05-25', 'YYYY-MM-DD').isValid();
moment('2015-02-29T13:02:49.073Z', "YYYY-MM-DDTHH:mm:ss", true).isValid();

Javascript: check date in future in dd/mm/yyyy format?

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>

Check if expression returns a valid date [duplicate]

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!";
}

Javascript : date automatically increments by +1 value (Convert String to Date object)

I use Date() function to convert string to date object . The problem is , If i give Date("April , 31 ,2012") it will take it as May , 01 , 2012 (for the rest of the days its working) Please check my approach is correct from the code below.
function TestDate(objValue,strError){
var ret=true;
var frmdate=objValue.value;
var datesplit=frmdate.split("-");
var y =datesplit[0];
var m=datesplit[1];
var d=datesplit[2];
var testdate;
// Create date object using given input data
testdate = new Date(m+"/"+d+"/"+y);
alert("Created date"+testdate.toString());
var td=testdate.getDate();
var tm=testdate.getMonth()+1;
var ty =testdate.getFullYear();
alert(d+"="+td);
alert(m+"="+tm);
alert(y+"="+ty);
var valid=((d==td) && (m==tm) && (y==ty));
alert(valid);
if(valid == false)
{
ret =false;
}
return ret;
}
As sayed by #ajreal in comments, April has only 30 days.
The internal date object increments the month to have a valid date.
The code:
testdate = new Date(m+"/"+d+"/"+y);
is depends on non-standard, implementation specific parsing of the string. Far better to use the data you started with to create a date unambiguously:
testdate = new Date(y, m - 1, d);
As for validating a date, a simple function using an ISO8601 compliant date of format yyyy-mm-dd is:
function validateDate(dateString) {
var bits = dateString.split('-');
var date = new Date(bits[0], bits[1] - 1, bits[2]);
return date && date.getFullYear() == bits[0] && date.getDate() == bits[2];
}
That way if the string passed to the function is turned into a date, you can check that the date so created matches the input. If not, it wasn't valid and the function returns false. It also returns false if the string doesn't get turned into a date.

Categories