admin管理员组文章数量:1125489
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
.
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
.
28 Answers
Reset to default 1561As 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]'
Be aware, that the instanceof
solution doesn't work when using multiple realms:
JavaScript execution environments (windows, frames, etc.) are each in their own realm. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance, [] instanceof window.frames[0].Array will return false, because Array.prototype !== window.frames[0].Array.prototype and arrays in the current realm inherit from the former.
You can use the following code:
(myvar instanceof Date) // returns true or false
Be aware, that this solution doesn't work when using multiple realms:
JavaScript execution environments (windows, frames, etc.) are each in their own realm. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance, [] instanceof window.frames[0].Array will return false, because Array.prototype !== window.frames[0].Array.prototype and arrays in the current realm inherit from the former.
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
.
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();
}
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)) { // isNaN wont accept a date in typescript, use date.getTime() instead to produce a number
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!");
}
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.
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
The best way I found is:
!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001")) // true
!isNaN(Date.parse("blabla")) // false
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
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!
const myDate = Date.now(); // 1679252208851
const myDate2 = new Date(); // Sun Mar 19 2023 20:56:59 GMT+0200 (Восточная Европа, стандартное время)
console.log(myDate instanceof Date); // false
console.log(myDate2 instanceof Date); // true
BUT
const myDate3 = new Date(myDate); // Sun Mar 19 2023 20:56:59 GMT+0200 (Восточная Европа, стандартное время)
console.log(myDate3 instanceof Date); // 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.
arrow function
const isValidDate = (value: any) => value instanceof Date && !isNaN(value);
Function:
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
In case you're using Node.js
you can check if an object is a Date
by using the isDate
method of the util
module like this.
const util = require('util');
const now = new Date();
console.log(util.types.isDate(now))
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'
Simply use moment
import moment from 'moment';
moment(myvar).isValid(); // return true or false
I've started leaning on this function.
/**
* @Returns Object type
* - betterTypeOf(); `undefined`
* - betterTypeOf(null); `null`
* - betterTypeOf(NaN); `number`
* - betterTypeOf(5); `number`
* - betterTypeOf({}); `object`
* - betterTypeOf([]); `array`
* - betterTypeOf(''); `string`
* - betterTypeOf(function () {}); `function`
* - betterTypeOf(/a/) `regexp`
* - betterTypeOf(new Date()) `date`
*/
export function betterTypeOf(obj) {
return Object.prototype.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
And then...
if (betterTypeOf(myDateVar) === 'date' {
console.log('it is a date')
}
This function will return true
if it's Date or false
otherwise:
function isDate(myDate) {
return myDate.constructor.toString().indexOf("Date") > -1;
}
Yet another variant:
Date.prototype.isPrototypeOf(myDateObject)
We can also validate it by below code
var a = new Date();
a.constructor === Date
/*
true
*/
with the following approach, you can even check date no to be "Invalid Date"
if(!!date.getDate()){
console.log('date is valid')
}
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)));
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();
}
}
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.
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"
/>
Simplest approach of detecting an valid date.
const isDate = ( str ) => {
let timestamp = Date.parse( str );
if (!isNaN(timestamp)) return new Date(timestamp);
return false
}
console.log( isDate("2020-11-11T12:12:55.123Z") )
console.log( isDate("17/July/2024") )
console.log( "getMonth: ", isDate("17/July/2024").getMonth() )
console.log( isDate("Invalid something") )
Couldn't you just use
function getFormatedDate(date) {
if (date.isValid()) {
var month = date.GetMonth();
}
}
本文标签: javascriptHow to check whether an object is a dateStack Overflow
版权声明:本文标题:javascript - How to check whether an object is a date? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736668173a1946776.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
Invalid Date
: stackoverflow.com/a/44198641/5846045 – Boghyon Hoffmann Commented Apr 11, 2020 at 11:45