Periksa apakah string adalah nilai tanggal

222

Apa cara yang mudah untuk memeriksa apakah suatu nilai adalah tanggal yang valid, format tanggal yang diketahui diperbolehkan.

Misalnya saya memiliki nilai-nilai 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000yang semua harus diakui sebagai nilai tanggal, dan nilai-nilai 200, 10, 350, yang seharusnya tidak diakui sebagai nilai tanggal. Apa cara termudah untuk memeriksa ini, jika ini mungkin? Karena stempel waktu juga akan diizinkan.

Thizzer
sumber

Jawaban:

45

Apakah Date.parse()cukup?

Lihat halaman Dokumentasi MDN relatifnya .

Asmor
sumber
27
Hati-hati dengan ini karena masih akan mengembalikan untuk tanggal yang tidak valid di bulan Februari, misalnya: 2013-02-31
leojh
62
Alasan lain untuk berhati-hati - angka diuraikan sebagai tanggal. Date.parse("4.3")adalah 986270400000.
Mogsdad
2
Saya mencoba biola dengan kedua kasus 'hati-hati' di atas: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ("4.3")); dan dalam kedua kasus (di firefox) itu mengembalikan NaN, jadi bagi saya, Date.parse tampaknya OK (saya menggunakan tanda hubung dan panjang yang benar sebelum parse).
Cloudranger
61
Maaf @Asmor, ini bukan jawaban yang benar. Date.parse akan mengurai string apa pun dengan nomor yang masuk.
jwerre
14
Date.parse ("My Name 8") datang sebagai 99662040000 yang salah. Saya menggunakan ini dan sekarang menderita.
Rohith
272

Pembaruan 2015

Ini adalah pertanyaan lama tetapi pertanyaan baru lainnya seperti:

ditutup sebagai duplikat dari yang satu ini, jadi menurut saya penting untuk menambahkan beberapa info baru di sini. Saya menulisnya karena saya takut berpikir bahwa orang benar-benar menyalin dan menempelkan beberapa kode yang diposting di sini dan menggunakannya dalam produksi.

Sebagian besar jawaban di sini baik menggunakan beberapa kalimat biasa kompleks yang cocok format hanya beberapa yang sangat spesifik dan benar-benar melakukannya dengan benar (seperti pencocokan 32 Januari sementara tidak cocok tanggal ISO yang sebenarnya seperti yang diiklankan - lihat demo ) atau mereka mencoba untuk lulus apa-apa untuk Datekonstruktor dan berharap yang terbaik.

Menggunakan Momen

Seperti yang saya jelaskan dalam jawaban ini, saat ini ada perpustakaan yang tersedia untuk itu: Moment.js

Ini adalah pustaka untuk mengurai, memvalidasi, memanipulasi, dan menampilkan tanggal dalam JavaScript, yang memiliki API yang jauh lebih kaya daripada fungsi penanganan tanggal JavaScript standar.

Ini adalah 12kB diperkecil / di-gzip dan berfungsi di Node.js dan tempat lain:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

Dengan menggunakan Momen, Anda bisa sangat spesifik tentang memeriksa tanggal yang valid. Terkadang sangat penting untuk menambahkan beberapa petunjuk tentang format yang Anda harapkan. Misalnya, tanggal seperti 06/22/2015 tampak seperti tanggal yang valid, kecuali jika Anda menggunakan format DD / MM / YYYY dalam hal ini tanggal ini harus ditolak karena tidak valid. Ada beberapa cara untuk memberi tahu Momen format apa yang Anda harapkan, misalnya:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

The trueArgumen ada begitu Moment tidak akan mencoba untuk mengurai input jika tidak persis sesuai dengan salah satu format yang disediakan (itu harus menjadi perilaku default menurut saya).

Anda dapat menggunakan format yang disediakan secara internal:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

Dan Anda dapat menggunakan berbagai format sebagai array:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

Lihat: DEMO .

Perpustakaan lainnya

Jika Anda tidak ingin menggunakan Moment.js, ada juga perpustakaan lain:

Pembaruan 2016

Saya membuat modul imoment yang seperti (bagian dari) Momen tetapi tanpa kejutan yang disebabkan oleh mutasi objek yang ada (lihat dokumen untuk info lebih lanjut).

Pembaruan 2018

Hari ini saya merekomendasikan menggunakan Luxon untuk manipulasi tanggal / waktu daripada Momen, yang (tidak seperti Momen) membuat semua objek tidak dapat diubah sehingga tidak ada kejutan buruk terkait dengan mutasi implisit pada tanggal.

Info lebih lanjut

Lihat juga:

Serangkaian artikel oleh Rob Gravelle tentang pustaka pengurai tanggal JavaScript:

Intinya

Tentu saja siapa pun dapat mencoba menemukan kembali roda, menulis ekspresi reguler (tetapi harap benar-benar membaca ISO 8601 dan RFC 3339 sebelum Anda melakukannya) atau memanggil konstruktor buit-in dengan data acak untuk mengurai pesan kesalahan seperti 'Invalid Date'(Anda yakin pesan ini adalah persis sama di semua platform? Di semua lokal? Di masa mendatang?) atau Anda dapat menggunakan solusi yang telah diuji dan menggunakan waktu Anda untuk memperbaikinya, bukan menciptakannya kembali. Semua perpustakaan yang tercantum di sini adalah sumber terbuka, perangkat lunak gratis.

rsp
sumber
4
bagaimana tepatnya seseorang harus menggunakan ini? moment("whatever 123").isValid()kembali true.
krivar
5
@krivar Cara terbaik untuk menggunakannya seperti ini: moment("06/22/2015", "DD/MM/YYYY", true).isValid();dengan format tanggal yang diharapkan disediakan secara eksplisit dan dengan argumen yang trueberarti pemeriksaan ketat. Saya memperbarui jawaban saya dengan lebih banyak info dan contoh yang lebih baik.
rsp
2
Meskipun sama, tetapi saya memvalidasi masukan pengguna dan saya tidak tahu format tanggal yang diharapkan ...
Jan Van der Haegen
3
@JanVanderHen Jika asumsi dapat dibuat bahwa 3/4/5 adalah tanggal yang valid dan begitu juga 1 April 2015 maka saya akan merekomendasikan menambahkan format tersebut (dan mungkin lebih banyak lagi) ke daftar eksplisit format yang didukung. Perhatikan bahwa 3/4/5 yang Anda sebutkan ambigu tanpa format eksplisit.
rsp
3
Ini bisa menjadi jawaban terbaik dan terpelihara dengan baik yang pernah saya lihat di SO
Phil3992
68

Beginilah cara saya memecahkan masalah ini di aplikasi yang saya kerjakan sekarang:

diperbarui berdasarkan umpan balik dari krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Neil Girardi
sumber
5
Saya perlu kembali (Tanggal baru (tanggal)). ToString ()! == "Tanggal Tidak Valid" untuk node. Perhatikan juga itu? true: false adalah redundan. hanya mengembalikan ekspresi sudah cukup di sini.
domenukk
Di IE8, new Date(date)tidak memberi Anda 'Tanggal Tidak Valid'.
krillgar
13
Ini bukan jawaban yang bagus. new Date(date) !== "Invalid Date"akan selalu mengembalikan nilai true karena ekspresi kiri akan mengembalikan objek Tanggal dengan nilai waktu NaN , yang tidak akan pernah menjadi ===string. Menggunakan =="berhasil" karena jenis konversi. Tetapi karena penguraian string tanggal sebagian besar masih bergantung pada implementasi, mengandalkannya untuk mengurai format acak, kami sangat cacat.
RobG
5
Tanggal baru ("469") hasil dalam Sel 01 Jan 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana
6
Ini mirip dengan jawaban benar yang diterima secara salah. isDate('Mac OS X 10.14.2')kembali benar di sini.
BradStell
26

new Date(date) === 'Invalid Date'hanya berfungsi di Firefox dan Chrome. IE8 (yang saya miliki di mesin saya untuk tujuan pengujian) memberikan NaN.

Seperti yang dinyatakan pada jawaban yang diterima, Date.parse(date)juga akan berfungsi untuk angka. Jadi untuk menyiasatinya, Anda juga dapat memeriksa bahwa itu bukan angka (jika itu adalah sesuatu yang ingin Anda konfirmasi).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}
krillgar
sumber
2
Saya menyadari itu beberapa tahun kemudian, tapi isNanitu bukan fungsi; kasus yang salah pada contoh pertama.
Tim Lewis
1
Tidak bekerja. Jika dateadalah Foostreet 1, kondisi Anda dievaluasi sebagai benar.
Fabian Picone
@FabianPicone - yah, secara teknis, ini berfungsi, tetapi memiliki kekurangan dengan parsesolusi berbasis lain : Date.parse("<text here> <number here>")kemungkinan akan diuraikan menjadi tanggal yang "valid", menyebabkan parsedDateuntuk tidak mengevaluasi NaN.
Oleg Valter
10

Bagaimana dengan sesuatu yang seperti ini? Ini akan menguji apakah itu objek Tanggal atau string tanggal:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Saya harus menyebutkan bahwa ini tidak menguji string berformat ISO tetapi dengan sedikit lebih banyak pekerjaan ke RegExp Anda harus baik.

jwerre
sumber
9

Tidak ada jawaban di sini yang memeriksa apakah tanggal tersebut tidak valid seperti 31 Februari. Fungsi ini membahas bahwa dengan memeriksa apakah bulan yang dikembalikan sama dengan bulan asli dan memastikan tahun yang valid telah disajikan.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 
ykay mengatakan Kembalikan Monica
sumber
Karena pertanyaannya bukan apakah memeriksa apakah suatu string adalah tanggal yang 'valid', tetapi hanya memeriksa apakah suatu string mewakili format tanggal.
Thizzer
@ Poin yang bagus. Saya tidak keberatan memperbaikinya tetapi saat membaca ulang pertanyaan Anda, saya bingung karena Anda mengatakan 10 seharusnya tidak divalidasi tetapi stempel waktu itu harus diizinkan.
ykay bilang Reinstate Monica
xD bahkan tidak menyadarinya, pertanyaan dari hari-hari saya sebelumnya dengan tanggal / cap waktu. Saya akan mencoba mengedit pertanyaan hari ini.
Thizzer
kenapa bulan ke-1 lalu bulan ke-1?
Kapil Raghuwanshi
1
Ini berhasil untuk saya karena, misalnya, jika Anda membuat tanggal baru dengan "30/2/2020", Chrome membuat tanggal yang valid untuk 1 Maret 2020. Jadi, hanya ini yang dapat saya lakukan untuk mendeteksi jenis tidak valid ini tanggal. Setelah membuat objek tanggal baru, saya membandingkan tahun, bulan, dan hari dengan string aslinya.
John Gilmer
8

Gunakan ekspresi reguler untuk memvalidasinya.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }
lpradhap.dll
sumber
6

Dengan mengacu pada semua komentar di atas, saya telah menemukan solusinya.

Ini berfungsi jika yang Datediteruskan dalam format ISO atau perlu dimanipulasi untuk format lain.

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

Anda bisa bermain di sini di JSFiddle.

Nikhil Zurunge
sumber
1
Solusi ini bekerja paling baik untuk saya karena string tanggal yang didukung aplikasi saya memiliki formatnya YYYY-MM-DD, jadi sepele untuk melampirkan T00:00:00.000Zdan menggunakan solusi ini untuk memeriksa string yang valid.
akselerasi
untuk javascript ini berfungsi, tetapi bagaimana menggunakannya dalam skrip ketikan.?
Sae
4
function isDate(dateStr) {
  return !isNaN(new Date(dateStr).getDate());
}
  • Ini akan bekerja pada semua browser karena tidak bergantung pada pemeriksaan "Tanggal Tidak Valid".
  • Ini akan bekerja dengan kode lama sebelum ES6.
  • Ini akan berfungsi tanpa perpustakaan apa pun.
  • Ini akan berfungsi terlepas dari format tanggal apa pun.
  • Ini tidak bergantung pada Date.parse yang gagal tujuan ketika nilai seperti "Spiderman 22" ada dalam string tanggal.
  • Ini tidak meminta kami untuk menulis RegEx apa pun.
Yuvraj Patil
sumber
1
Halo! Meskipun kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan memberikan indikasi batasan dan asumsi apa yang berlaku.
Brian
Saat menambahkan jawaban untuk pertanyaan berusia delapan tahun dengan jawaban yang diterima dan 19 jawaban yang ada, sangat penting untuk menunjukkan aspek baru apa dari pertanyaan yang menjadi alamat jawaban Anda, jika tidak, itu mungkin tampak seperti jawaban duplikat dan akan dihapus.
Jason Aller
Saya telah menambahkan penjelasannya. Terima kasih atas bimbingannya.
Yuvraj Patil
1
hati-hati, isDate ('4.3') dan isDate ('xxx 8') mengembalikan keduanya true
Boris
Pernyataan tentang tidak mengandalkan Date.parse, sayangnya, tidak benar karena baik yang disebutkan sebelumnya dan Date()konstruktor dipanggil dengan fungsi string yang hampir sama.
Oleg Valter
3

Berikut adalah peningkatan fungsi yang hanya menggunakan Date.parse():

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

Catatan: Date.parse () akan mengurai angka: misalnya Date.parse(1)akan mengembalikan tanggal. Jadi di sini kita periksa apakah sbukan angka, jika itu tanggal.

A-Sharabiani
sumber
2
ini tidak bekerja karena lulus 'tes 2' akan lulus sebagai tanggal sebenarnya. diuji dalam versi terbaru chrome
user1751287
2

Saya akan melakukan ini

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Mainkan disini

kiranvj
sumber
2
Ini tidak berfungsi di Chrome saat ini, mungkin di browser lain. Saya mengubah string yang disediakan EXAMPLE STRING 12345dan mengembalikan "Tanggal valid".
1

Ini versi minimalisnya.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
Tuan Polywhirl
sumber
2
Masih tidak berhasil untuk contoh saya:isDate("&nbsp; 1")
Tomas
@Tom Anda harus memeriksa apakah nilainya mengandung karakter spasi sebelum menentukan apakah itu tanggal. Masalah Anda adalah kasus khusus yang perlu ditangani oleh logika pengontrol Anda.
Tn. Polywhirl
1
Memeriksa karakter spasi putih tidak diperlukan karena string 1 Januari 2020 adalah tanggal valid yang berisi spasi. Metode Anda tidak memperhitungkan ini.
Kirstin Walsh
1

Fungsi yang dapat dipanggil ini bekerja dengan sempurna, mengembalikan nilai true untuk tanggal yang valid. Pastikan untuk menelepon menggunakan tanggal dengan format ISO (tttt-bb-hh atau tttt / bb / hh):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}
Peter DK
sumber
1
Itu bagus, tetapi tidak menjawab pertanyaan itu sepenuhnya. Secara khusus, ini tidak berfungsi untuk '2009-11-10T07: 00: 00 + 0000', salah satu contoh yang diberikan.
amadan
Jangan berpikir ini berfungsi sebagaimana mestinya validateDate ('2016-12-30T08: 00: 00.000Z') // false
Jose Browne
Terlepas dari apakah ini berhasil atau tidak, ini dapat disederhanakan sebagaireturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung
1

Saya tahu ini adalah pertanyaan lama tetapi saya menghadapi masalah yang sama dan melihat bahwa tidak ada jawaban yang berfungsi dengan baik - secara khusus menyingkirkan nomor (1.200.345, dll ..) dari tanggal, yang merupakan pertanyaan asli. Berikut adalah metode yang agak tidak ortodoks yang dapat saya pikirkan dan tampaknya berhasil. Harap tunjukkan jika ada kasus di mana itu akan gagal.

if(sDate.toString() == parseInt(sDate).toString()) return false;

Ini adalah garis untuk menyingkirkan angka. Dengan demikian, seluruh fungsi akan terlihat seperti:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));

peekolo
sumber
1
console.log("hello 1 ", isDate("hello 1 "));kembali benar
Yohanes
kamu benar! apakah kamu punya solusi Sampai sekarang saya pikir tidak ada jawaban di sini yang benar-benar menjawab pertanyaan dengan tepat!
peekolo
"100%", persentase, mengembalikan true
toddmo
0

apakah baik-baik saja untuk memeriksa fungsi terkait Tanggal tersedia untuk objek untuk menemukan apakah itu objek Tanggal atau bukan?

Suka

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;
Kishore Relangi
sumber
0

Beginilah akhirnya saya melakukannya. Ini tidak mencakup semua format. Anda harus menyesuaikannya. Saya memiliki kendali atas formatnya, jadi ini berfungsi untuk saya

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }
kheya
sumber
-1

Oke, ini pertanyaan lama, tetapi saya menemukan solusi lain saat memeriksa solusi di sini. Bagi saya bekerja untuk memeriksa apakah fungsi getTime () ada di objek tanggal:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
m.steini
sumber
-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

Sebuah ringan perpustakaan siap Anda: Day.js

Neo
sumber
2
Ini pada dasarnya beriklan di StackOverflow, jangan lakukan itu.
c4sh
-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Secara default, ini disetel ke TRUE. Jadi, bahkan string dengan format yang salah mengembalikan nilai yang baik.

Saya telah menggunakannya seperti ini:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }
Anupam Mahapatra
sumber
7
... javascript ?!
Artpark
-6

Coba ini:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}
Andrew Hare
sumber
6
Ini tidak berhasil untuk saya. Pertama, var dalam kondisi tidak mengurai, tetapi jika Anda menghapusnya dan mencoba sesuatu seperti ini: if (date = new Date ("rubbish")) {alert (date); } Meskipun tanggalnya sampah, peringatan akan tetap dijalankan karena fungsi Tanggal akan mengembalikan "Tanggal Tidak Valid" (setidaknya di firefox) sehingga kondisi dievaluasi menjadi benar. Saya kira jika beberapa browser mengembalikan null pada tanggal tidak valid, maka itu akan berfungsi pada browser tersebut. Mungkin ada inkonsistensi browser di sini.
Cloudranger