JavaScriptで「無効な日付」の日付インスタンスを検出する


1494

JSの有効な日付オブジェクトと無効な日付オブジェクトの違いを教えたいのですが、方法がわかりませんでした。

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'

isValidDate関数を書くためのアイデアはありますか?

  • Date.parse日付文字列の解析にはAshをお勧めします。これにより、日付文字列が有効かどうかを確認する信頼できる方法が提供されます。
  • 可能であれば、APIにDateインスタンスを受け入れさせ、それが有効かどうかをチェック/アサートできるようにしたいと思います。Borgarのソリューションはそれを行いますが、ブラウザー間でテストする必要があります。よりエレガントな方法があるかどうかも疑問です。
  • Ashは、APIにDateインスタンスをまったく受け入れさせないことを検討させました。これは検証が最も簡単です。
  • Borgarは、Dateインスタンスのテストと、Dateの時間値のテストを提案しました。日付が無効な場合、時間の値はNaNです。ECMA-262で確認したところ、この動作は標準であり、まさに私が求めているものです。

18
:あなたはに関数の本体を変更することで、if文を削除することができreturn ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
styfle

3
@styfle-スタイル設定だと思います。型チェックと等式ロジックを分離する方が明確です。
orip '27 / 06/27

26
@orip談話は、質問でかなり非推奨となるものです。その背後にある理論的根拠を学ぶために関連するメタトピックを参照してください。質問自体に自分の質問への回答を含めることは、サイトポリシーに違反します。OTOH、回答に感謝し、回答に「編集」があることは典型的な綿毛です。SOとは何か、それをどのように使用するかを知らず、それを学びたくない人物としてあなたに最高評価の質問をしたい場合-私のゲストになってください。

14
@orip:「失われた」わけではありません。もう一度見たい場合は、質問の変更履歴がまだ乱雑です。しかしそれは質問には属していません。37k担当者では、これを知っている必要があります。
明度レース軌道に

6
編集戦争を停止してください。この質問の編集はmetaで議論されています。この投稿をさらに編集/ロールバックしないでください。以前の編集/ロールバックに同意しない場合、またはそれらに関するコメントがある場合は、ここではなく、そのメタスレッドに投稿してください。
ランディン

回答:


1304

ここに私がそれをする方法があります:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d.getTime())) {  // d.valueOf() could also work
    // date is not valid
  } else {
    // date is valid
  }
} else {
  // not a date
}

更新[2018-05-31]:他のJSコンテキスト(外部ウィンドウ、フレーム、またはiframe)からのDateオブジェクトに関心がない場合は、この単純な形式が推奨される場合があります。

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

21
instanceofはフレーム間で分割されます。ダックタイピングもうまく機能します:validDate == d && d.getTime &&!isNaN(d.getTime()); -質問は一般的な効用関数に関するものなので、私はより厳格である方を好みます。
ボーガー、

11
@Borgar、ちょうど私の答えを見つけた:「マルチフレームDOM環境でのスクリプト作成に関して問題が発生します。簡単に言えば、あるiframe内で作成されたArrayオブジェクトは、別のiframe内で作成された配列と[[Prototype]]を共有しません。 。それらのコンストラクターは異なるオブジェクトであるため、instanceofとコンストラクターの両方のチェックが失敗します。」
アッシュ

64
あなたd.getTimeだけでも必要はありませんisNan(d)
TecHunter 2013年

8
:次のように単純化することができd instanceof Date && !isNaN(d.getTime())
Zorgatone

5
答えてくれてありがとう、でも@Borgarと@blueprintChrisのコメントを強調したいと思います。1たとえば、数字を解析したとしても、Mon Jan 01 2001 00:00:00実際には日付である有効な日付が残っていますが、アプリケーションの目的では完全に役に立たないのです。 。したがって、少なくとも私の場合には、さらにいくつかの入力検証が必要です。この答えdateObjectDate
dnhyde

264

を使用new Date()する代わりに、以下を使用する必要があります。

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse()1970年1月1日からのミリ秒数を表す整数であるタイムスタンプを返します。NaN指定された日付文字列を解析できない場合に返されます。


119
-1 Dunnoなぜこれが非常に多くの賛成票を投じているのかDate.parseは実装に依存しており、一般的な日付文字列を解析することは間違いなく信頼されていません。一般的なブラウザで正しく解析される単一の形式はなく、使用中のすべての形式よりもはるかに少ない(ただし、最終的にはES5で指定されているISO8601形式で問題ないはずです)。
RobG、2012年

1
を使用する場合、new Date('foo')それは基本的にDate.parse('foo')メソッドと同等です。参照:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…つまり、@ RobGが言ったことは、それにも当てはまります。
golddragon007

2
このテストはChromeでは失敗します。たとえば、ChromeのDate.parse( 'AAA-0001')は数値を示します。
Nick

失敗しました...すべての数値を検出します
Hos Mercury

109

あなたはの妥当性をチェックすることができますDateオブジェクトをd介して、

d instanceof Date && isFinite(d)

フレーム間の問題を回避するために、instanceofチェックを

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

呼び出しgetTime()のようにBorgarの答えはとして不必要であるisNaN()isFinite()の両方が暗黙的に数値に変換します。


これをChromeで試してください-Object.prototype.toString.call(new Date( "2013-07-09T19:07:9Z"))。「[オブジェクト日付]」を返します。したがって、「2013-07-09T19:07:9Z」は有効な日付である必要があります。そうではありません。var dateStr = new Date( "2013-07-09T19:07:9Z");を実行すると、Chromeで再び確認できます。dateStr無効な日付を返します。
タンタン2013

2
@Tintin:それisFinite()が目的です- 小切手toString.call()instanceof一部を置き換えるだけです
Christoph

「[object Date]」との比較は、英語以外のブラウザでも機能しますか?疑わしい。
kristianp

2
@kristianpは実際にはおそらくECMAScript仕様の一部であり、おそらく一部でもあります。しかし、はい、それは醜いようです。
binki

私にとって、ここでの最初のアプローチは最良のオプションですが、を使用isFiniteすることの実際の利点があるかどうかはわかりませんisNaN(両方ともでうまく機能しますDate(Infinity))。さらに、反対の条件が必要な場合は、少し単純になりますif (!(date instanceof Date) || isNaN(date))
Andrew

86

私の解決策は、有効な日付オブジェクトを取得するかどうかを単にチェックすることです:

実装

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

使用法

var d = new Date("lol");

console.log(d.isValid()); // false

d = new Date("2012/09/11");

console.log(d.isValid()); // true

28
isNaNNaNをテストするためのより明確な方法です
orip

1
そして、まだ、あなたは常に独自のバージョン:)書く人を見つける documentcloud.github.com/underscore/docs/...
アッシュ・クラーク

4
underscore.jsを尊重しているので、これはいくつかの研究を促しました。isNaN("a") === trueながら、("a" !== "a") === false。考える価値があります。+1
orip

8
ここで見つけた3つの主要なソリューションのパフォーマンスをテストしました。おめでとうございます、あなたは勝者です!jsperf.com/detecting-an-invalid-date
zVictor 2014

2
@Aliこれは有効な日付オブジェクトです。 new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time)。文字列を日付コンストラクタに渡す場合は、信頼できる結果を得るために標準化された文字列を渡す必要があります。具体的には、「文字列は、Date.parse()メソッドで認識される形式である必要があります」。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
アッシュ・クラーク

71

有効な日付を確認するための最短の回答

if(!isNaN(date.getTime()))

2
唯一の問題は、日付が日付型でない場合です。JSエラーが発生します。
Andrew

@Andrewは、日付オブジェクトを作成する必要があります。すでにオブジェクトがある場合は、次を使用しますdate && !isNaN(date.getTime())
abhirathore2006

dateタイプが日付でない場合でも、JSエラーが発生します。次に例を示しますvar date = 4; date && !isNaN(date.getTime());
Andrew

@Andrew use date instanceof Date && !isNaN(date.getTime())
abhirathore2006

3
そう、8年前の他の答えと同じように。:P stackoverflow.com/a/1353945/2321042
Andrew

45

あなたは単にmoment.jsを使うことができます

次に例を示します。

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

ドキュメントの検証セクションは非常に明確です。

また、次の解析フラグは無効な日付になります。

  • overflow:13か月目、32日目(うるう年でない場合は2月29日)、367日目などの日付フィールドのオーバーフロー。オーバーフローには無効なユニットのインデックスが含まれます。 #invalidAtに一致させる(下記参照)。-1はオーバーフローがないことを意味します。
  • invalidMonth:無効な月の名前(例:moment( 'Marbruary'、 'MMMM');)。無効な月の文字列自体、またはnullが含まれています。
  • empty:moment( 'this is nonsense');のように、解析できないものを含む入力文字列。ブール。
  • 等。

出典:http : //momentjs.com/docs/


6
非常に簡単に実装できる最良のソリューションは、任意のフォーマットで機能し(私の場合はdd / MM / yyyyです)、うるう年も知っており、無効な日付(つまり29/02/2015)を有効な日付自体に変換しません(つまり2015年3月30日)。formad dd / MM / yyyyで日付をチェックするには、ちょうど使用しなければなりませんでしたmoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin

3
このモーメントの使用は廃止されました:(
James Sumners '25 / 09/25

2
この使用は減価償却されていません。フォーマット文字列なしでモーメント(入力)を呼び出すと、入力がISOフォーマットされていない限り、減価償却されます。
2016

2
多くの日付を処理する場合、この方法は非常に遅くなる可能性があります。そのような場合は正規表現を使用する方が良いでしょう。
Grid Trekkor 16

2
moment.jsの使い方は簡単かもしれませんが、莫大なオーバーヘッドです。このライブラリは巨大です。私はあなたの答えに反対票を投じました。
ミック

38

jQuery UI DatePickerウィジェットには、形式と有効性をチェックする非常に優れた日付検証ユーティリティメソッドがある(たとえば、2013年1月33日の日付は許可されていない)ことを述べておきます。

ページの日付ピッカーウィジェットをUI要素として使用したくない場合でも、その.jsライブラリをいつでもページに追加してから、検証するメソッドを呼び出して、検証する値を渡すことができます。作業をさらに簡単にするために、JavaScriptのDateオブジェクトではなく、文字列を入力として受け取ります。

参照:http : //api.jqueryui.com/datepicker/

メソッドとしてはリストされていませんが、ユーティリティ関数としてあります。ページで「parsedate」を検索すると、以下が見つかります。

$ .datepicker.parseDate(format、value、settings)-指定されたフォーマットで文字列値から日付を抽出します。

使用例:

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

(日付形式の指定に関する詳細情報はhttp://api.jqueryui.com/datepicker/#utility-parseDateにあります

上記の例では、「01/03/2012」は指定された形式のカレンダーで有効な日付であるため、アラートメッセージは表示されません。ただし、たとえば「stringval」を「13/04/2013」と等しくした場合、値「13/04/2013」はカレンダー有効ではないため、アラートメッセージが表示されます。

渡された文字列値が正常に解析された場合、 'testdate'の値は、渡された文字列値を表すJavascript Dateオブジェクトになります。そうでない場合は、未定義になります。


3
英語/ロケール以外の日付形式で作業する最初の回答であることへの賛成票
斧。

26

私はクリストフのアプローチが本当に好きでした(しかし、投票するほどの評判はありませんでした)。私が使用するために、私は常にDateオブジェクトを持っていることを知っているので、valid()メソッドで日付を拡張しました。

Date.prototype.valid = function() {
  return isFinite(this);
}

これで私はこれを書くことができ、コードでisFiniteをチェックするよりもはるかに説明的です...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }

10
プロトタイプを拡張しますか?それは大きなJavaScriptです。
Jasdeep Khalsa

私のためにisFinite完全に働いたので賛成票を投じます。しかし、はい、プロトタイプを拡張しても意味がありません。!isFinite上のDate事実キャッチするDateですInvalid Date。また、私のコンテキストはノード内にあることに注意してください。
Staghouse


17

このスクリプトでtxDate.valueの有効な形式を確認できます。形式が正しくない場合、Dateオブジェクトはインスタンス化されず、dtにnullを返します。

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

そして@MiFが短い方法で提案したように

 if(isNaN(new Date(...)))

isNaN(new Date(...))-シンプルで短いメソッド
MiF

1
@MiFはい、私はあなたの提案で私の答えを更新します;)感謝
ユセフェリ2017年

16

次のコードを使用して、年、月、日付の値を検証します。

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

詳細については、JavaScriptのチェック日付を参照してください。


str使用されていません。
samis 2016

12

ここにはすでに複雑な答えが多すぎますが、単純な行で十分です(ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

またはES6でも:

Date.prototype.isValid = d => !isNaN(Date.parse(d));

1
MDNから:「Date.parse()メソッドは日付の文字列表現を解析し、1970年1月1日00:00:00 UTCまたはNaN ...からのミリ秒数を返します。」関数は整数またはNaNを返します。次に、isNaN()関数は、元の値が有効な日付オブジェクトであったかどうかを示すクリーンなブール値を提供します。これでスポットチェックを行うのに十分ですが、上記の例では、このメソッドをDateオブジェクトにアタッチして、プログラム全体で機能を簡単に利用および読み取りできるようにします。
マックスワイルダー

dがブール値の場合、Nanではない0または1を受け取ります!!
davcup

@davcupはを使用してテストしたばかりでDate.parse(true)、NaNを正しく取得しています。
Sebastien H.

12

この小さなスニペットに非常に近い回答がいくつかありました。

JavaScriptの方法:

function isValidDate(dateObject){ return new Date(dateObject).toString() !== 'Invalid Date'; }
isValidDate(new Date('WTH'));

TypeScriptの方法:

const isValidDate = dateObject => new Date(dateObject ).toString() !== 'Invalid Date';
isValidDate(new Date('WTH'));

1
何かが足りないのかどうかわかりませんが、新しいDate()を2度実行しても意味がありませんか?
Jon Catmull

2
後者はTypeScriptとは関係ありません。それは完全に有効なJSです。
hackel

9

素敵な解決策!私の補助関数のライブラリに含まれていますが、次のようになっています。

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

9

これはちょうど私のために働いた

new Date('foo') == 'Invalid Date'; //is true

しかし、これはうまくいきませんでした

new Date('foo') === 'Invalid Date'; //is false

5
これはブラウザに依存していると思います。
Barrypicker 14年

@barrypickerこれはブラウザに依存しているとはどういう意味ですか?
Ajil O.

あなたは行うことができます: `${new Date('foo')}` === 'Invalid Date'
ダニエルVrut

9

Angular.jsプロジェクトの場合、以下を使用できます。

angular.isDate(myDate);

3
これは、無効な日付で初期化された日付オブジェクトをテストする場合にtrueを返します。
dchhetri

6

2/31/2012などの日付を検証しようとすると、これらの回答はどれも機能しません(Safari 6.0でテスト済み)。ただし、31を超える日付を試すとうまくいきます。

だから私は少し力ずくでしなければなりませんでした。日付が次の形式であると想定しますmm/dd/yyyy。私は@broox回答を使用しています:

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

(new Date( '2/30/2014'))。valid()はtrueを返します
Andre Figueiredo

1
私はこれに答えてからしばらく時間が経過しましたが、&& value.split('/')[0] == (d.getMonth()+1);
Dex

使用することnew Date('string date')と等価であるDate.parse('string date')、次を参照してください。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...あなたが偽の真または偽の値を取得する可能性がありますので。
golddragon007

5

上記の解決策のどれも私にとってはうまくいきませんでしたが、うまくいったことは

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

上記のコードは、JSが02/31/2012を03/02/2012にすると、無効であることを示します


3
わかりましたが、これは文字列がM / D / Y形式の日付であるかどうかをテストします。「有効な日付オブジェクトと無効な日付オブジェクトの違い」ではありません。これが実際に問題となっていることではありません。
Borgar

フォーマットに対してチェックされる理由は、解析後に日付が変更されたかどうかをチェックするためです
John

OPは、フォーマットされた文字列ではなくブール値を返すメソッドを求めていませんか?
barrypicker 14年

1
サンプルコードはブール値を返しますが、このフォーマット設定は、いくつかの無効なケースのテストに役立ちます。
ジョン14年

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

4

この関数を書きました。文字列パラメータを渡すと、この形式 "dd / MM / yyyy"に基づいて有効な日付かどうかが判断されます。

ここにテストがあります

入力:「ははは」、出力:false。

入力: "29/2/2000"、出力:true。

入力: "29/2/2001"、出力: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;
    }
}

4

Date.prototype.toISOStringRangeError無効な日付で(少なくともChromiumとFirefoxでは)スローします。これを検証の手段として使用できますがisValidDate、その必要はありません(EAFP)。そうでなければ:

function isValidDate(d)
{
  try
  {
    d.toISOString();
    return true;
  }
  catch(ex)
  {
    return false;    
  }    
}

1
ECMA-262の定義でエラーを投げるのは唯一の機能のようです。15.9.5.43 Date.prototype.toISOString()この関数は、このDateオブジェクトが表すインスタンスを時間で表すString値を返します。文字列の形式は、15.9.1.15で定義された日時文字列形式です。すべてのフィールドが文字列に存在します。タイムゾーンは常にUTCであり、サフィックスZで示されます。このオブジェクトの時刻値が有限数でない場合、RangeError例外がスローされます。
Henry Liu

3

ボーガーのアプローチに触発されて、コードが日付を検証するだけでなく、実際に日付が実際の日付であることを確認しました。つまり、2011年9月31日や2011年2月2日などの日付は許可されません。

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

しかし...上記のメソッド(@Borgarと他のメソッド)はすでにこのタイプの有効性をチェックしています...問題は発生しません。
2011

ボーガーはそうではありません-彼の答えに対する彼自身のコメントを見てください。
EML

1
このソリューションは、国がdd/MM/yyyy表記法を使用している場合にのみ機能します。また、true有効な場合に返されます。有効で'Invalid date!'ない場合は、1つのタイプのみを返します。
A1rPun

3

特定のオブジェクトがあるかどうかを確認するために、その周辺で見つかった最高のパフォーマンス結果を組み合わせました。

結果は次のとおりです。

function isValidDate(input) {
  if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
    return false;

  var time = input.getTime();
  return time === time;
};

2

文字列への日付オブジェクトは、両方のフィールドが有効な日付であるかどうかを検出するより簡単で信頼できる方法です。たとえば、日付入力フィールドにこの「-------」を入力するとします。上記の回答の一部は機能しません。

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}.');

2

選んだ答えは素晴らしく、私も使っています。ただし、ユーザーの日付入力を検証する方法を探している場合、無効な構築引数のように見えるものを有効なものに変換することについて、Dateオブジェクトは非常に永続的であることに注意する必要があります。次の単体テストコードは、ポイントを示しています。

QUnit.test( "valid date test", function( assert ) {
  //The following are counter-examples showing how the Date object will 
  //wrangle several 'bad' dates into a valid date anyway
  assert.equal(isValidDate(new Date(1980, 12, 15)), true);
  d = new Date();
  d.setFullYear(1980);
  d.setMonth(1);
  d.setDate(33);
  assert.equal(isValidDate(d), true);
  assert.equal(isValidDate(new Date(1980, 100, 150)), true);
  //If you go to this exterme, then the checker will fail
  assert.equal(isValidDate(new Date("This is junk")), false);
  //This is a valid date string
  assert.equal(isValidDate(new Date("November 17, 1989")), true);
  //but is this?
  assert.equal(isValidDate(new Date("November 35, 1989")), false);  
  //Ha!  It's not.  So, the secret to working with this version of 
  //isValidDate is to pass in dates as text strings... Hooboy
  //alert(d.toString());
});

2
function isValidDate(strDate) {
    var myDateStr= new Date(strDate);
    if( ! isNaN ( myDateStr.getMonth() ) ) {
       return true;
    }
    return false;
}

このように呼ぶ

isValidDate(""2015/5/2""); // => true
isValidDate(""2015/5/2a""); // => false

2

最高評価の回答に基づく準備完了機能:

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

2

シンプルでエレガントなソリューション:

const date = new Date(`${year}-${month}-${day} 00:00`)
const isValidDate = (Boolean(+date) && date.getDate() == day)

ソース:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] JavaScriptのnew Date()に誤った日付が表示される


1
date.getDate() == day日付が有効かどうかを判断するには不十分です。元の日付形式は、日付が有効かどうかに関係なく、一部の実装では無効な日付を返します。また、「1970-01-01 00:00」は、正しく解析された場合にfalseを返します(つまり、Boolean(+new Date("1970-01-01"))falseを返します)。
RobG

警告:これはSafari
Vigrant

Safariでは、「const date = new Date(year, month, day); 月は0のようにこのようにインデックスが作成されます」という形式を使用する場合に機能します。正しく並べるために1を引く必要がある場合があります。
Vigrant

1

これのいくつかは長いプロセスだと思います。以下に示すように短くできます。

 function isValidDate(dateString) {
        debugger;
        var dateStringSplit;
        var formatDate;

        if (dateString.length >= 8 && dateString.length<=10) {
            try {
                dateStringSplit = dateString.split('/');
                var date = new Date();
                date.setYear(parseInt(dateStringSplit[2]), 10);
                date.setMonth(parseInt(dateStringSplit[0], 10) - 1);
                date.setDate(parseInt(dateStringSplit[1], 10));

                if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {
                    return true;
                }
                else {
                    return false;
                }

            } catch (e) {
                return false;
            }
        }
        return false;
    }

3
質問では、文字列ではなく、無効なDateインスタンスを見つける方法を尋ねました。さらに、日付はフォワードスラッシュ以外のもので区切ることはできないと誰が言っていますか?
Jon z

1

日付のint 1ベースのコンポーネントの場合:

var is_valid_date = function(year, month, day) {
    var d = new Date(year, month - 1, day);
    return d.getFullYear() === year && (d.getMonth() + 1) === month && d.getDate() === day
};

テスト:

    is_valid_date(2013, 02, 28)
&&  is_valid_date(2016, 02, 29)
&& !is_valid_date(2013, 02, 29)
&& !is_valid_date(0000, 00, 00)
&& !is_valid_date(2013, 14, 01)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.