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
.
This question is related to
javascript
date
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
An approach using a try/catch
function getFormatedDate(date = new Date()) {_x000D_
try {_x000D_
date.toISOString();_x000D_
} catch (e) {_x000D_
date = new Date();_x000D_
}_x000D_
return date;_x000D_
}_x000D_
_x000D_
console.log(getFormatedDate());_x000D_
console.log(getFormatedDate('AAAA'));_x000D_
console.log(getFormatedDate(new Date('AAAA')));_x000D_
console.log(getFormatedDate(new Date(2018, 2, 10)));
_x000D_
Couldn't you just use
function getFormatedDate(date) {
if (date.isValid()) {
var month = date.GetMonth();
}
}
This is a pretty simple approach and doesn't experience a lot of the edge cases in the existing answers.
// Invalid Date.getTime() will produce NaN
if (date instanceof Date && date.getTime()) {
console.log("is date!");
}
It won't fire with other objects like numbers, makes sure the value is actually a Date
(rather than an object that looks like one), and it avoids Invalid Dates
.
If you are using Typescript you could check using the Date type:
const formatDate( date: Date ) => {}
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
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.
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]"
. Because date.toString()
overrides its parent method, we need to .call
or .apply
the method from Object.prototype
directly which ..
instanceof
or Date.prototype.isPrototypeOf
.!isNaN(date)
finally checks whether the value was not an Invalid Date
.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();
}
You could check if a function specific to the Date object exists:
function getFormatedDate(date) {
if (date.getMonth) {
var month = date.getMonth();
}
}
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'
This function will return true
if it's Date or false
otherwise:
function isDate(myDate) {
return myDate.constructor.toString().indexOf("Date") > -1;
}
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.
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();
}
}
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!
Yet another variant:
Date.prototype.isPrototypeOf(myDateObject)
The best way I found is:
!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001")) // true
!isNaN(Date.parse("blabla")) // false
You can use the following code:
(myvar instanceof Date) // returns true or false
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.
Source: Stackoverflow.com