Mendeteksi tanggal "tanggal tidak valid" misalnya dalam JavaScript


1494

Saya ingin memberi tahu perbedaan antara objek tanggal yang valid dan tidak valid di JS, tetapi tidak dapat mengetahui caranya:

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'

Adakah ide untuk menulis suatu isValidDatefungsi?

  • Ash direkomendasikan Date.parseuntuk penguraian string tanggal, yang memberikan cara otoritatif untuk memeriksa apakah string tanggal valid.
  • Apa yang saya inginkan, jika mungkin, adalah agar API saya menerima contoh Tanggal dan untuk dapat memeriksa / menegaskan apakah itu valid atau tidak. Solusi Borgar melakukan itu, tetapi saya perlu mengujinya di seluruh browser. Saya juga bertanya-tanya apakah ada cara yang lebih elegan.
  • Ash membuat saya menganggap API saya tidak dapat menerima Dateinstance sama sekali, ini akan lebih mudah untuk divalidasi.
  • Borgar menyarankan pengujian untuk Datecontoh, dan kemudian pengujian untuk nilai Datewaktu itu. Jika tanggal tidak valid, nilai waktu adalah NaN. Saya memeriksa dengan ECMA-262 dan perilaku ini dalam standar, yang persis apa yang saya cari.

18
Anda dapat menghapus pernyataan if dengan mengubah tubuh fungsi ke:return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
styfle

3
@styfle - kira itu adalah preferensi gaya: Saya merasa lebih jelas untuk memisahkan pemeriksaan tipe dari logika kesetaraan.
orip

26
@orip wacana adalah persis apa yang sangat tidak disarankan dalam pertanyaan. Silakan merujuk ke topik meta yang relevan untuk mempelajari alasan di baliknya. Menempatkan jawaban untuk memiliki pertanyaan dalam pertanyaan itu sendiri bertentangan dengan kebijakan situs. OTOH, berterima kasih atas tanggapan dan memiliki "EDIT" dalam jawaban Anda adalah tipuan biasa. Jika Anda ingin agar pertanyaan berperingkat teratas mengidentifikasi Anda sebagai orang yang tidak tahu apa itu SO dan bagaimana menggunakannya, dan tidak ingin mempelajarinya - jadilah tamu saya.

14
@orip: Itu bukan "hilang"; itu masih mengacaukan riwayat revisi pertanyaan jika Anda ingin melihatnya lagi. Tapi itu tidak termasuk dalam pertanyaan. Pada rep 37k Anda harus tahu ini.
Lightness Races di Orbit

6
Mohon hentikan perang edit. Suntingan pada pertanyaan ini dibahas dalam meta . Harap jangan edit / kembalikan pos ini lebih lanjut. Jika Anda tidak setuju dengan pengeditan / rollback sebelumnya atau ada komentar mengenai hal itu, silakan posting di thread meta itu dan tidak di sini.
Lundin

Jawaban:


1304

Begini cara saya melakukannya:

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
}

Pembaruan [2018-05-31] : Jika Anda tidak peduli dengan objek Tanggal dari konteks JS lainnya (jendela eksternal, bingkai, atau iframe), bentuk yang lebih sederhana ini mungkin lebih disukai:

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

21
contoh pecah di seluruh frame. Mengetik bebek juga bisa bekerja: validDate == d && d.getTime &&! IsNaN (d.getTime ()); - Karena pertanyaannya adalah untuk fungsi utilitas umum saya lebih suka lebih ketat.
Borgar

11
@Borgar, baru saja menemukan jawaban saya: "Masalah muncul ketika datang ke scripting di lingkungan DOM multi-frame. Singkatnya, objek Array yang dibuat dalam satu iframe tidak berbagi [[Prototipe]] dengan array yang dibuat dalam iframe lain . Konstruktor mereka adalah objek yang berbeda dan kedua instof dan konstruktor gagal. "
Ash

64
Anda bahkan tidak perlu d.getTimehanyaisNan(d)
TecHunter

8
Bisa disederhanakan seperti ini:d instanceof Date && !isNaN(d.getTime())
Zorgatone

5
Terima kasih atas jawabannya, tetapi saya ingin menekankan komentar @Borgar dan @blueprintChris: jika saya menguraikan digit 1misalnya saya masih akan memiliki tanggal yang valid yang menghasilkan Mon Jan 01 2001 00:00:00tanggal, namun untuk keperluan aplikasi saya itu sama sekali tidak berguna . Jadi, setidaknya ada beberapa validasi input yang diperlukan dalam kasus saya. Jawaban ini memvalidasi dateObjectbukan Date!
dnhyde

264

Alih-alih menggunakan new Date()Anda harus menggunakan:

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

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

Date.parse()mengembalikan timestamp, bilangan bulat yang mewakili jumlah milidetik sejak 01 / Jan / 1970. Ini akan kembali NaNjika tidak dapat menguraikan string tanggal yang disediakan.


119
-1 Entah mengapa ini memiliki begitu banyak suara, Date.parsetergantung pada implementasi dan jelas tidak dapat dipercaya untuk mengurai string tanggal umum. Tidak ada format tunggal yang diuraikan dengan benar di browser populer, apalagi semua yang digunakan (meskipun akhirnya format ISO8601 yang ditentukan dalam ES5 harus ok).
RobG

1
Jika Anda menggunakan new Date('foo')itu pada dasarnya setara dengan Date.parse('foo')metode. Lihat: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Jadi apa yang dikatakan @RobG, itu juga berlaku untuk itu.
golddragon007

2
Tes ini akan gagal di Chrome. Misalnya, Date.parse ('AAA-0001') di Chrome memberi saya nomor.
Nick

gagal ... mendeteksi semua nilai numerik
Hos Mercury

109

Anda dapat memeriksa validitas Dateobjek dmelalui

d instanceof Date && isFinite(d)

Untuk menghindari masalah lintas-bingkai, seseorang dapat mengganti instanceofcek dengan

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

Panggilan untuk getTime()seperti dalam jawaban Borgar tidak perlu karena isNaN()dan isFinite()keduanya secara implisit dikonversi ke nomor.


Coba ini di chrome - Object.prototype.toString.call (Tanggal baru ("2013-07-09T19: 07: 9Z")). Ini akan mengembalikan "[Tanggal objek]". Oleh karena itu, menurut Anda, "2013-07-09T19: 07: 9Z", harus menjadi tanggal yang valid. Tapi ternyata tidak. Anda dapat memverifikasinya, lagi di chrome, dengan melakukan var dateStr = Tanggal baru ("2013-07-09T19: 07: 9Z"); dateStr Ini akan mengembalikan tanggal yang tidak valid.
Tintin

2
@Tintin: untuk itulah isFinite()- toString.call()hanya pengganti instanceofbagian dari cek
Christoph

Akankah membandingkan dengan '[Tanggal objek]' berfungsi dengan browser non-Inggris? Aku meragukan itu.
kristianp

2
@ Kristianp sebenarnya mungkin dan bahkan mungkin bagian dari spesifikasi ECMAScript. Tapi, ya, sepertinya jelek.
binki

Bagi saya pendekatan pertama di sini adalah pilihan terbaik, meskipun aku tidak yakin apakah ada keuntungan dunia nyata menggunakan isFinitelebih isNaN(baik bekerja dengan baik dengan Date(Infinity)). Selain itu, jika Anda ingin kondisi sebaliknya, itu akan sedikit lebih sederhana: if (!(date instanceof Date) || isNaN(date)).
Andrew

86

Solusi saya adalah hanya memeriksa apakah Anda mendapatkan objek tanggal yang valid:

Penerapan

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

Pemakaian

var d = new Date("lol");

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

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

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

28
isNaNadalah cara yang lebih eksplisit untuk menguji NaN
orip

1
Namun, Anda selalu menemukan orang-orang menulis versi mereka sendiri :) documentcloud.github.com/underscore/docs/…
Ash Clarke

4
karena saya menghormati garis bawah. Ini mendorong beberapa penelitian. isNaN("a") === true, sementara ("a" !== "a") === false. Ini layak untuk dipikirkan. +1
orip

8
Saya menguji kinerja untuk 3 solusi utama yang saya temukan di sini. Selamat, Anda adalah pemenangnya! jsperf.com/detecting-an-invalid-date
zVictor

2
@ Ali Itu adalah objek tanggal yang valid. new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time). Jika Anda meneruskan string ke konstruktor tanggal, Anda harus meneruskan string standar untuk mendapatkan hasil yang andal. Secara khusus, "String harus dalam format yang dikenali oleh metode Date.parse ()". developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ash Clarke

71

jawaban terpendek untuk memeriksa tanggal yang valid

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

2
Satu-satunya masalah adalah jika tanggal bukan tipe Tanggal; Anda mendapatkan kesalahan JS.
Andrew

@Andrew Anda perlu membuat Objek tanggal dan jika Anda sudah memiliki objek kemudian gunakandate && !isNaN(date.getTime())
abhirathore2006

Itu masih memberi Anda kesalahan JS jika datebukan tipe Date. Sebagai contoh: var date = 4; date && !isNaN(date.getTime());.
Andrew

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

3
Benar, seperti jawaban lain dari 8 tahun yang lalu. : P stackoverflow.com/a/1353945/2321042
Andrew

45

Anda cukup menggunakan moment.js

Berikut ini sebuah contoh:

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

Bagian validasi dalam dokumentasi cukup jelas.

Dan juga, parsing flag berikut menghasilkan tanggal yang tidak valid:

  • overflow: Limpahan bidang tanggal, seperti bulan ke-13, hari ke-32 dalam sebulan (atau tanggal 29 Februari pada tahun-tahun non-kabisat), hari ke-367 ​​dalam setahun, dll. Luapan berisi indeks unit yang tidak valid untuk mencocokkan #invalidAt (lihat di bawah); -1 berarti tidak ada luapan.
  • invalidMonth: Nama bulan yang tidak valid, seperti saat ('Marbruary', 'MMMM') ;. Berisi string bulan yang tidak valid itu sendiri, atau null.
  • empty: String input yang tidak mengandung apa-apa yang dapat diuraikan, seperti momen ('this is nonsense') ;. Boolean.
  • Dll

Sumber: http://momentjs.com/docs/


6
Solusi terbaik, sangat mudah diimplementasikan, bekerja dengan pemformatan apa pun (kasus saya adalah dd / MM / tttt), juga mengetahui tahun kabisat dan tidak mengonversi tanggal yang tidak valid (mis. 29/02/2015) menjadi yang valid dengan sendirinya (mis. 30/03/2015). Untuk memeriksa tanggal di formad hh / MM / tttt Saya baru saja harus menggunakanmoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin

3
Penggunaan Moment ini telah ditinggalkan :(
James Sumners

2
Penggunaan ini belum disusutkan. Momen panggilan (input) tanpa string format disusutkan (kecuali jika inputnya berformat ISO).
Chet

2
Metode ini bisa sangat lambat saat memproses banyak tanggal. Lebih baik menggunakan regex dalam kasus tersebut.
Grid Trekkor

2
Penggunaan moment.js mungkin sederhana, tetapi merupakan overhead yang sangat besar. Perpustakaan ini BESAR. Saya menurunkan jawaban Anda.
Mick

38

Ingin menyebutkan bahwa widget DatePicker jQuery UI memiliki metode utilitas validator tanggal yang sangat baik yang memeriksa format dan validitas (misalnya, tidak ada tanggal 01/33/2013 yang dibolehkan).

Bahkan jika Anda tidak ingin menggunakan widget datepicker pada halaman Anda sebagai elemen UI, Anda selalu dapat menambahkan pustaka .js ke halaman Anda dan kemudian memanggil metode validator, meneruskan nilai yang ingin Anda validasikan ke dalamnya. Untuk membuat hidup lebih mudah, dibutuhkan string sebagai input, bukan objek Tanggal JavaScript.

Lihat: http://api.jqueryui.com/datepicker/

Itu tidak terdaftar sebagai metode, tetapi itu ada - sebagai fungsi utilitas. Cari halaman untuk "parsedate" dan Anda akan menemukan:

$ .datepicker.parseDate (format, nilai, pengaturan) - Ekstrak tanggal dari nilai string dengan format yang ditentukan.

Contoh penggunaan:

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

(Info lebih lanjut menentukan format tanggal dapat ditemukan di http://api.jqueryui.com/datepicker/#utility-parseDate )

Dalam contoh di atas, Anda tidak akan melihat pesan peringatan karena '01 / 03/2012 'adalah tanggal yang valid dengan kalender dalam format yang ditentukan. Namun jika Anda membuat 'stringval' sama dengan '13 / 04/2013 ', misalnya, Anda akan mendapatkan pesan peringatan, karena nilai '13 / 04/2013' tidak valid kalender.

Jika nilai string yang lewat berhasil diurai, nilai 'testdate' akan menjadi objek Tanggal Javascript yang mewakili nilai string yang diteruskan. Jika tidak, itu tidak akan ditentukan.


3
Suara positif untuk menjadi jawaban pertama yang bekerja dengan format tanggal non Inggris / lokal.
kapak.

26

Saya sangat menyukai pendekatan Christoph (tetapi tidak memiliki cukup reputasi untuk memilihnya). Untuk penggunaan saya, saya tahu saya akan selalu memiliki objek Tanggal jadi saya hanya memperpanjang tanggal dengan metode yang valid ().

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

Sekarang saya bisa menulis ini dan itu jauh lebih deskriptif daripada hanya memeriksa isFinite dalam kode ...

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

10
Memperluas prototipe? Itu JavaScript besar, tidak, tidak, tidak!
Jasdeep Khalsa

Upvoting karena isFiniteberhasil untuk saya dengan sempurna. Tapi ya, tidak ada gunanya memperpanjang prototipe. !isFinitepada Datewasiat menangkap fakta bahwa Dateitu Invalid Date. Juga perlu dicatat konteks saya ada di dalam Node.
Staghouse

23
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());

5
Itu sama @Borgar menulis 2 tahun lalu ... Apa yang baru ??
kebiruan

11
Ini dua baris bukannya pernyataan jika bersarang jelek.
Cypher

17

Anda dapat memeriksa format txDate.value dengan skirpt ini. jika itu dalam format yang salah Date obejct tidak dipasang dan mengembalikan null ke dt.

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

Dan seperti yang disarankan @ MiF secara singkat

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

isNaN (Tanggal baru (...)) - metode sederhana dan pendek
MiF

1
@ MIF ya, saya memperbarui jawaban saya dengan saran Anda;) terima kasih
Yuseferi

16

Saya menggunakan kode berikut untuk memvalidasi nilai untuk tahun, bulan dan tanggal.

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

Untuk detailnya, lihat Periksa tanggal dalam javascript


strtidak digunakan.
samis

12

Sudah terlalu banyak jawaban rumit di sini, tetapi garis sederhana sudah cukup (ES5):

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

atau bahkan di ES6:

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

1
Dari MDN: "Metode Date.parse () mem-parsing representasi string dari sebuah tanggal, dan mengembalikan jumlah milidetik sejak 1 Januari 1970, 00:00:00 UTC atau NaN ..." Jadi menjalankan tanggal potensial melalui ini fungsi mengembalikan bilangan bulat atau NaN. Kemudian fungsi isNaN () akan memberikan boolean bersih yang memberi tahu Anda apakah nilai asli adalah objek tanggal yang valid atau tidak. Ini cukup untuk melakukan pemeriksaan spot, tetapi contoh di atas kemudian menempelkan metode ini ke objek Date untuk membuat fungsionalitas mudah tersedia dan dapat dibaca di seluruh program Anda.
Max Wilder

jika d adalah boolean Anda akan menerima 0 atau 1 yang bukan Nan !!
davcup

@ davcup baru saja diuji menggunakan Date.parse(true), saya mendapatkan NaN dengan benar.
Sebastien H.

12

Saya melihat beberapa jawaban yang mendekati potongan kecil ini.

Cara JavaScript:

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

Cara TypeScript:

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

1
Tidak yakin apakah saya melewatkan sesuatu tetapi Tidak melakukan Tanggal baru () dua kali tidak berguna?
Jon Catmull

2
Yang terakhir tidak ada hubungannya dengan TypeScript. Ini adalah JS yang benar-benar valid.
retas

9

Solusi bagus! Termasuk di perpustakaan fungsi bantu saya, sekarang tampilannya seperti ini:

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

Ini hanya bekerja untuk saya

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

Namun ini tidak berhasil

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

5
Saya percaya ini tergantung pada browser.
barrypicker

@barrypicker Apa maksud Anda ini tergantung pada browser?
Ajil O.

Anda dapat melakukan: `${new Date('foo')}` === 'Invalid Date'
Daniele Vrut

9

Untuk proyek Angular.js Anda dapat menggunakan:

angular.isDate(myDate);

3
Ini mengembalikan true ketika menguji objek tanggal yang telah diinisialisasi dengan Tanggal Tidak Valid.
dchhetri

6

Tidak satu pun dari jawaban ini yang berfungsi untuk saya (diuji di Safari 6.0) ketika mencoba memvalidasi tanggal seperti 2/31/2012, namun, mereka berfungsi dengan baik ketika mencoba tanggal yang lebih dari 31.

Jadi saya harus sedikit memaksa. Dengan asumsi tanggal dalam format mm/dd/yyyy. Saya menggunakan jawaban @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

(Tanggal baru ('2/30/2014')). valid () mengembalikan true
Andre Figueiredo

1
Sudah lama sejak saya menjawab ini tetapi Anda mungkin perlu kedua kondisi kembali, termasuk&& value.split('/')[0] == (d.getMonth()+1);
Dex

Menggunakan new Date('string date')setara dengan Date.parse('string date'), lihat: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… sehingga Anda mungkin mendapatkan nilai false true atau false.
golddragon007

5

Tidak satu pun dari solusi di atas yang berhasil bagi saya apa yang berhasil adalah

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

kode di atas akan melihat ketika JS membuat 02/31/2012 menjadi 03/02/2012 yang tidak valid


3
Oke, tetapi ini menguji apakah string adalah tanggal dalam format M / D / Y, bukan "perbedaan antara objek tanggal yang valid dan tidak valid". Sebenarnya ini bukan pertanyaan apa.
Borgar

alasan mengapa itu diperiksa terhadap format adalah untuk memeriksa apakah tanggal telah berubah setelah diuraikan
John

Bukankah OP meminta metode untuk mengembalikan Boolean, bukan string yang diformat?
barrypicker

1
Kode sampel mengembalikan boolean, formating memainkan bagian dalam pengujian untuk beberapa kasus yang tidak valid.
John

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

Saya sudah menulis fungsi ini. Berikan parameter string dan itu akan menentukan apakah itu tanggal yang valid atau tidak berdasarkan format ini "dd / MM / yyyy".

ini dia ujian

input: "hahaha", output: false.

input: "29/2/2000", output: true.

input: "29/2/2001", output: 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.toISOStringmelempar RangeError(setidaknya di Chromium dan Firefox) pada tanggal yang tidak valid. Anda dapat menggunakannya sebagai sarana validasi dan mungkin tidak perlu isValidDateseperti itu (EAFP). Kalau tidak, itu:

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

1
Tampaknya itu adalah satu-satunya fungsi yang melempar kesalahan dengan definisi ECMA-262. 15.9.5.43 Date.prototype.toISOString () Fungsi ini mengembalikan nilai String yang mewakili instance dalam waktu yang diwakili oleh objek Date ini. Format String adalah format string Tanggal Waktu yang ditentukan dalam 15.9.1.15. Semua bidang hadir dalam String. Zona waktu selalu UTC, dilambangkan dengan akhiran Z. Jika nilai waktu dari objek ini tidak terbatas Number a RangeError exception dilempar.
Henry Liu

3

Terinspirasi oleh pendekatan Borgar, saya telah memastikan bahwa kode tidak hanya memvalidasi tanggal, tetapi benar-benar memastikan tanggal tersebut adalah tanggal nyata, yang berarti bahwa tanggal seperti 31/09/2011 dan 29/02/2011 tidak diperbolehkan.

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

Tapi ... metode di atas (@ Borgar dan yang lainnya) sudah memeriksa jenis validitas ini ... Saya tidak bisa mendapatkan masalah.
kebiruan

Borgar tidak - melihat komentarnya sendiri untuk jawabannya.
EML

1
Solusi ini hanya berfungsi ketika negara Anda menggunakan dd/MM/yyyynotasi. Juga, itu kembali trueketika itu valid & 'Invalid date!'jika tidak, lebih baik kembalikan hanya 1 jenis.
A1rPun

3

Saya menggabungkan hasil kinerja terbaik yang saya temukan di sekitar itu memeriksa apakah objek yang diberikan:

Hasilnya adalah sebagai berikut:

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

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

2

Objek tanggal ke string adalah cara yang lebih sederhana dan andal untuk mendeteksi jika kedua bidang adalah tanggal yang valid. mis. Jika Anda memasukkan "-------" ke kolom input tanggal. Beberapa jawaban di atas tidak akan berfungsi.

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

Jawaban yang dipilih sangat bagus, dan saya juga menggunakannya. Namun, jika Anda mencari cara untuk memvalidasi input tanggal pengguna, Anda harus menyadari bahwa objek Date sangat gigih membuat argumen konstruksi yang tidak valid menjadi yang valid. Kode tes unit berikut menggambarkan poin:

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

Sebut saja seperti ini

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

2

Fungsi siap berdasarkan jawaban berperingkat teratas:

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

Solusi sederhana dan elegan:

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

sumber:

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

[2] Tanggal salah ditampilkan dalam Tanggal baru () dalam JavaScript


1
date.getDate() == daytidak cukup untuk menentukan apakah tanggal tersebut valid. Format tanggal asli akan mengembalikan tanggal yang tidak valid dalam beberapa implementasi terlepas dari apakah tanggal tersebut valid atau tidak. Juga "1970-01-01 00:00" jika diurai dengan benar akan Boolean(+new Date("1970-01-01"))menghasilkan false (mis. Return false).
RobG

PERINGATAN: Ini tidak akan berfungsi di Safari
Vigrant

Ini akan berfungsi di Safari jika Anda menggunakan format const date = new Date(year, month, day); Perhatikan bahwa bulan 0 diindeks dengan cara ini sehingga Anda mungkin harus mengurangi satu untuk berbaris dengan benar.
Vigrant

1

Saya pikir beberapa dari ini adalah proses yang panjang. Kita dapat memotongnya seperti yang ditunjukkan di bawah ini:

 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
Pertanyaan yang diajukan adalah bagaimana menemukan instance Date yang tidak valid, bukan string, dan selain itu: siapa bilang kencan tidak dapat dibatasi oleh sesuatu selain dari garis miring?
Jon z

1

Untuk komponen berdasarkan tanggal 1 int:

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

Tes:

    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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.