How to check whether an object is a date?
JavascriptDateJavascript Problem Overview
I have an annoying bug in on a webpage:
> date.GetMonth() is not a function
So, I suppose that I am doing something wrong. The variable date
is not an object of type Date
. How can I check for a datatype in Javascript? I tried to add a if (date)
, but it doesn't work.
function getFormatedDate(date) {
if (date) {
var month = date.GetMonth();
}
}
So, if I want to write defensive code and prevent the date (which is not one) to be formatted, how do I do that?
Thanks!
UPDATE: I don't want to check the format of the date, but I want to be sure that the parameter passed to the method getFormatedDate()
is of type Date
.
Javascript Solutions
Solution 1 - Javascript
As an alternative to duck typing via
typeof date.getMonth === 'function'
you can use the instanceof
operator, i.e. But it will return true for invalid dates too, e.g. new Date('random_string')
is also instance of Date
date instanceof Date
This will fail if objects are passed across frame boundaries.
A work-around for this is to check the object's class via
Object.prototype.toString.call(date) === '[object Date]'
Solution 2 - Javascript
You can use the following code:
(myvar instanceof Date) // returns true or false
Solution 3 - Javascript
In order to check if the value is a valid type of the standard JS-date object, you can make use of this predicate:
function isValidDate(date) {
return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
date
checks whether the parameter was not a falsy value (undefined
,null
,0
,""
, etc..)Object.prototype.toString.call(date)
returns a native string representation of the given object type - In our case"[object Date]"
. Becausedate.toString()
overrides its parent method, we need to.call
or.apply
the method fromObject.prototype
directly which ..
- Bypasses user-defined object type with the same constructor name (e.g.: "Date")
- Works across different JS contexts (e.g. iframes) in contrast to
instanceof
orDate.prototype.isPrototypeOf
.
!isNaN(date)
finally checks whether the value was not anInvalid Date
.
Solution 4 - Javascript
The function is getMonth()
, not GetMonth()
.
Anyway, you can check if the object has a getMonth property by doing this. It doesn't necessarily mean the object is a Date, just any object which has a getMonth property.
if (date.getMonth) {
var month = date.getMonth();
}
Solution 5 - Javascript
As indicated above, it's probably easiest to just check if the function exists before using it. If you really care that it's a Date
, and not just an object with a getMonth()
function, try this:
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
This will create either a clone of the value if it's a Date
, or create an invalid date. You can then check if the new date's value is invalid or not.
Solution 6 - Javascript
This is a pretty simple approach if you're not concerned about iframes / other contexts.
// isNaN(Invalid Date) == true
if (date instanceof Date && !isNaN(date)) {
console.log("is date!");
}
- Checks if object is actually a
Date
and not something that looks like one. Any object could have agetMonth
function. - Ensures the Date is not an
Invalid Date
- Doesn't pass a value into
new Date()
where a number or even a string could be turned into a Date.
If you need to support iframes and different contexts you can use the accepted answer but add an extra check to identify invalid dates.
// isNaN(Invalid Date) == true
if (Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date)) {
console.log("is date!");
}
Solution 7 - Javascript
For all types I cooked up an Object prototype function. It may be of use to you
Object.prototype.typof = function(chkType){
var inp = String(this.constructor),
customObj = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9),
regularObj = Object.prototype.toString.apply(this),
thisType = regularObj.toLowerCase()
.match(new RegExp(customObj.toLowerCase()))
? regularObj : '[object '+customObj+']';
return chkType
? thisType.toLowerCase().match(chkType.toLowerCase())
? true : false
: thisType;
}
Now you can check any type like this:
var myDate = new Date().toString(),
myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String
[Edit march 2013] based on progressing insight this is a better method:
Object.prototype.is = function() {
var test = arguments.length ? [].slice.call(arguments) : null
,self = this.constructor;
return test ? !!(test.filter(function(a){return a === self}).length)
: (this.constructor.name ||
(String(self).match ( /^function\s*([^\s(]+)/im)
|| [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Some = function(){ /* ... */}
,Other = function(){ /* ... */}
,some = new Some;
2..is(String,Function,RegExp); //=> false
2..is(String,Function,Number,RegExp); //=> true
'hello'.is(String); //=> true
'hello'.is(); //-> String
/[a-z]/i.is(); //-> RegExp
some.is(); //=> 'ANONYMOUS_CONSTRUCTOR'
some.is(Other); //=> false
some.is(Some); //=> true
// note: you can't use this for NaN (NaN === Number)
(+'ab2').is(Number); //=> true
Solution 8 - Javascript
The best way I found is:
!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001")) // true
!isNaN(Date.parse("blabla")) // false
Solution 9 - Javascript
UnderscoreJS and Lodash have a function called .isDate()
which appears to be exactly what you need. It's worth looking at their respective implementations: Lodash isDate, UnderscoreJs
Solution 10 - Javascript
Instead of all the workarounds you can use the following:
dateVariable = new Date(date);
if (dateVariable == 'Invalid Date') console.log('Invalid Date!');
I found this hack better!
Solution 11 - Javascript
I have been using a much simpler way but am not sure if this is only available in ES6 or not.
let a = {name: "a", age: 1, date: new Date("1/2/2017"), arr: [], obj: {} };
console.log(a.name.constructor.name); // "String"
console.log(a.age.constructor.name); // "Number"
console.log(a.date.constructor.name); // "Date"
console.log(a.arr.constructor.name); // "Array"
console.log(a.obj.constructor.name); // "Object"
However, this will not work on null or undefined since they have no constructor.
Solution 12 - Javascript
arrow function
const isValidDate = (value: any) => value instanceof Date && !isNaN(value);
Function:
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
Solution 13 - Javascript
You could check if a function specific to the Date object exists:
function getFormatedDate(date) {
if (date.getMonth) {
var month = date.getMonth();
}
}
Solution 14 - Javascript
Also you can use short form
function getClass(obj) {
return {}.toString.call(obj).slice(8, -1);
}
alert( getClass(new Date) ); //Date
or something like this:
(toString.call(date)) == 'Date'
Solution 15 - Javascript
This function will return true
if it's Date or false
otherwise:
function isDate(myDate) {
return myDate.constructor.toString().indexOf("Date") > -1;
}
Solution 16 - Javascript
Yet another variant:
Date.prototype.isPrototypeOf(myDateObject)
Solution 17 - Javascript
An approach using a try/catch
function getFormattedDate(date = new Date()) {
try {
date.toISOString();
} catch (e) {
date = new Date();
}
return date;
}
console.log(getFormattedDate());
console.log(getFormattedDate('AAAA'));
console.log(getFormattedDate(new Date('AAAA')));
console.log(getFormattedDate(new Date(2018, 2, 10)));
Solution 18 - Javascript
with the following approach, you can even check date no to be "Invalid Date"
if(!!date.getDate()){
console.log('date is valid')
}
Solution 19 - Javascript
Simply use moment
import moment from 'moment';
moment(myvar).isValid(); // return true or false
Solution 20 - Javascript
Actually date will be of type Object
. But you can check if the object has getMonth
method and if it is callable.
function getFormatedDate(date) {
if (date && date.getMonth && date.getMonth.call) {
var month = date.getMonth();
}
}
Solution 21 - Javascript
Inspired by this answer, this solution works in my case(I needed to check whether the value recieved from API is a date or not):
!isNaN(Date.parse(new Date(YourVariable)))
This way, if it is some random string coming from a client, or any other object, you can find out if it is a Date-like object.
Solution 22 - Javascript
I had some issues with React hooks where the Date would come in later / lazy loaded and then the initial state can't be null, it won't pass ts checks, but apparently an empty Object does the trick then! :)
const [birthDate, setBirthDate] = React.useState({})
<input
value={birthDate instanceof Date ? birthDate.toISOString() : ''}
name="birthDay"
/>
Solution 23 - Javascript
Solution 24 - Javascript
If you are using Typescript you could check using the Date type:
const formatDate( date: Date ) => {}
Solution 25 - Javascript
Couldn't you just use
function getFormatedDate(date) {
if (date.isValid()) {
var month = date.GetMonth();
}
}