如何判断一个对象是否是日期?

我在一个网页上有一个恼人的bug:

date. GetMonth()不是函数

所以,我想我做错了什么。变量date不是类型Date的对象。如何在Javascript中检查数据类型?我尝试添加if (date),但它不起作用。

function getFormatedDate(date) {if (date) {var month = date.GetMonth();}}

所以,如果我想编写防御性代码并防止日期(不是一个)被格式化,我该怎么做?

谢谢!

更新:我不想检查日期的格式,但我想确定传递给方法getFormatedDate()的参数是Date类型的。

699447 次浏览

函数是getMonth(),不是GetMonth()

无论如何,您可以通过执行此操作来检查对象是否具有getMonth属性。这并不一定意味着该对象是Date,只是任何具有getMonth属性的对象。

if (date.getMonth) {var month = date.getMonth();}

您可以检查Date对象是否存在特定的函数:

function getFormatedDate(date) {if (date.getMonth) {var month = date.getMonth();}}

如上所述,在使用它之前检查该函数是否存在可能是最简单的。如果你真的关心它是一个Date,而不仅仅是一个带有getMonth()函数的对象,请尝试以下操作:

function isValidDate(value) {var dateWrapper = new Date(value);return !isNaN(dateWrapper.getDate());}

如果值是Date,这将创建一个值的克隆,或者创建一个无效的日期。然后您可以检查新日期的值是否无效。

作为通过鸭子输入的替代方案

typeof date.getMonth === 'function'

您可以使用instanceof运算符,即对于无效日期,它也会返回true,例如new Date('random_string')也是Date的实例

date instanceof Date

如果对象跨帧边界传递,这将失败。

一个解决方法是通过检查对象的类

Object.prototype.toString.call(date) === '[object Date]'

实际上date将是类型Object。但是您可以检查对象是否有getMonth方法以及它是否可以调用。

function getFormatedDate(date) {if (date && date.getMonth && date.getMonth.call) {var month = date.getMonth();}}

对于所有类型,我制作了一个对象原型函数。它可能对你有用

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

现在你可以像这样检查任何类型:

var myDate     = new Date().toString(),myRealDate = new Date();if (myRealDate.typof('Date')) { /* do things */ }alert( myDate.typof() ); //=> String

[2013年3月]基于进展的洞察力,这是一个更好的方法:

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] );}// usagevar Some = function(){ /* ... */},Other = function(){ /* ... */},some = new Some;2..is(String,Function,RegExp);        //=> false2..is(String,Function,Number,RegExp); //=> true'hello'.is(String);                   //=> true'hello'.is();                         //-> String/[a-z]/i.is();                        //-> RegExpsome.is();                            //=> 'ANONYMOUS_CONSTRUCTOR'some.is(Other);                       //=> falsesome.is(Some);                        //=> true// note: you can't use this for NaN (NaN === Number)(+'ab2').is(Number);                 //=> true

您可以使用以下代码:

(myvar instanceof Date) // returns true or false

如果是Date,则此函数将返回true,否则返回false

function isDate(myDate) {return myDate.constructor.toString().indexOf("Date") > -1;}

UnderScoreJSLodash有一个名为.isDate()的函数,它似乎正是您需要的。值得查看它们各自的实现:Lodash是日期UnderScoreJs

您也可以使用短格式

function getClass(obj) {return {}.toString.call(obj).slice(8, -1);}alert( getClass(new Date) ); //Date

或者像这样:

(toString.call(date)) == 'Date'

我发现最好的方法是:

!isNaN(Date.parse("some date test"))//!isNaN(Date.parse("22/05/2001"))  // true!isNaN(Date.parse("blabla"))  // false

你就不能用

function getFormatedDate(date) {if (date.isValid()) {var month = date.GetMonth();}}

为了检查该值是否是标准JS-date对象的有效类型,您可以使用以下谓词:

function isValidDate(date) {return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);}
  1. date检查参数是否不是假值undefinednull0""等)
  2. Object.prototype.toString.call(date)返回给定对象类型的本机字符串表示-在我们的例子"[object Date]"中。因为#2覆盖其父方法,我们需要.call.apply直接从Object.prototype中的方法…
    • 绕过具有相同构造函数名称的用户定义对象类型(例如:“Date”)
    • 对比#0Date.prototype.isPrototypeOf中跨不同的JS上下文(例如ifram)工作。
  3. !isNaN(date)最后检查该值是否不是Invalid Date

我一直在使用一种更简单的方法,但不确定这是否仅在ES6中可用。

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"

但是,这将不适用于null或未定义,因为它们没有构造函数。

另一个变体:

Date.prototype.isPrototypeOf(myDateObject)

使用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)));

您可以使用以下方法代替所有变通方法:

dateVariable = new Date(date);if (dateVariable == 'Invalid Date') console.log('Invalid Date!');

我发现这个hack更好!

我们也可以通过下面的代码验证它

var a = new Date();a.constructor === Date/*true*/

在此处输入图片描述

这个答案的启发,这个解决方案适用于我的情况(我需要检查从API接收的值是否是日期):

!isNaN(Date.parse(new Date(YourVariable)))

这样,如果它是来自客户端或任何其他对象的随机字符串,您可以找出它是否是类似日期的对象。

这是一个非常简单的方法,如果你不关心ifram/其他上下文。

// isNaN(Invalid Date) == trueif (date instanceof Date && !isNaN(date)) {console.log("is date!");}
  • 检查对象是否实际上是Date而不是看起来像Date的东西。任何对象都可以有getMonth函数。
  • 确保日期不是Invalid Date
  • 不会将值传递给new Date(),其中数字甚至字符串都可以转换为Date。

如果您需要支持iFramework和不同的上下文,您可以使用接受的答案,但添加额外的检查以识别无效日期。

// isNaN(Invalid Date) == trueif (Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date)) {console.log("is date!");}

如果您使用的是TypeScript,您可以使用Date类型进行检查:

const formatDate( date: Date ) => {}

使用以下方法,您甚至可以检查日期否为“无效日期”

if(!!date.getDate()){console.log('date is valid')}

我对React钩子有一些问题,其中Date稍后会出现/延迟加载,然后初始状态不能为空,它不会通过ts检查,但显然一个空的Object会起作用!:)

const [birthDate, setBirthDate] = React.useState({})
<inputvalue={birthDate instanceof Date ? birthDate.toISOString() : ''}name="birthDay"/>

箭头函数

const isValidDate = (value: any) => value instanceof Date && !isNaN(value);

功能:

function isValidDate(d) {return d instanceof Date && !isNaN(d);}

只需利用瞬间

import moment from 'moment';
moment(myvar).isValid(); //  return true or false