Bir dizenin tarih değeri olup olmadığını kontrol edin


207

Bir değerin geçerli bir tarih olup olmadığını kontrol etmenin kolay bir yolu nedir, bilinen herhangi bir tarih biçimine izin verilir.

Ben değerlerine sahip örnek için 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000tüm tarih değerleri olarak kabul edilmelidir hangi ve değerler 200, 10, 350, tarih değeri olarak kabul edilmemelidir hangi. Mümkünse bunu kontrol etmenin en basit yolu nedir? Çünkü zaman damgalarına da izin verilecekti.


Yanıtlar:


41

Misiniz Date.parse()yeterli?

Göreli MDN Belgeleri sayfasına bakın .


24
Buna dikkat edin, çünkü Şubat ayında hala geçersiz tarihler için geri dönüş yapacak, örneğin: 2013-02-31
leojh

58
Dikkatli olmanın bir başka nedeni - sayılar tarih olarak ayrıştırılır. Date.parse("4.3")olduğunu 986270400000.
Mogsdad

Yukarıdaki 'dikkat' vakalarının her ikisiyle de bir keman denedim: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ( "4.3")); ve her iki durumda da (firefox'ta) NaN döndürdü, bu yüzden benim için Date.parse tamam görünüyor (yine de ayrıştırmadan önce tire ve doğru uzunluk için geçerli oluyorum).
Cloudranger

55
Üzgünüm @Asmor, bu doğru bir cevap değil. Date.parse içindeki herhangi bir dizeyi ayrıştırır.
jwerre

11
Date.parse ("Adım 8") 99662040000 olarak geliyor ve bu yanlış. Bunu kullandım ve şimdi acı çekiyorum.
Rohith

250

2015 Güncellemesi

Bu eski bir soru ama diğer yeni sorular:

Bu bir kopya olarak kapalı olsun, bu yüzden burada bazı taze bilgi eklemek önemli olduğunu düşünüyorum. Bunu yazıyorum çünkü insanların burada yayınlanan kodların bazılarını kopyalayıp yapıştırarak üretimde kullandığını düşünmekten korktum.

Buradaki yanıtların çoğu ya sadece çok belirli biçimlerle eşleşen bazı karmaşık düzenli ifadeler kullanır ve bunu yanlış yapar (gerçek ISO tarihini reklamı yapılanla eşleştirmeden 32 Ocak'ı eşleştirmek gibi - demoya bakın ) ya da herhangi bir şeyi kurucuya aktarmaya çalışırlar Dateve en iyisini diliyorum.

Anı Kullanma

Bu cevapta açıkladığım gibi şu anda bunun için bir kütüphane var: Moment.js

Standart JavaScript tarih işleme işlevlerinden çok daha zengin bir API'ye sahip olan JavaScript'teki tarihleri ​​ayrıştırmak, doğrulamak, değiştirmek ve görüntülemek için bir kitaplıktır.

12kB küçültülmüş / sıkıştırılmış ve Node.js ve diğer yerlerde çalışır:

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

Moment'i kullanarak geçerli tarihleri ​​kontrol etme konusunda çok spesifik olabilirsiniz. Bazen beklediğiniz format hakkında bazı ipuçları eklemek çok önemlidir. Örneğin, DD / AA / YYYY biçimini kullanmadığınız sürece 06/22/2015 gibi bir tarih geçerli bir tarihe benzemektedir; bu durumda bu tarih geçersiz olarak reddedilmelidir. Moment'e hangi formatı beklediğinizi söylemenin birkaç yolu vardır, örneğin:

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

trueArgüman Moment o değilse giriş ayrıştırmak denemez yüzden orada tam olarak sunulan biçimlerden birinde uygun (Bence varsayılan bir davranış olmalıdır).

Dahili olarak sağlanan bir biçimi kullanabilirsiniz:

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

Ve bir dizi olarak birden çok biçimi kullanabilirsiniz:

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

Bakınız: DEMO .

Diğer kütüphaneler

Moment.js'yi kullanmak istemiyorsanız, başka kütüphaneler de vardır:

2016 Güncellemesi

An (ama bir altkümesi) gibi, ama mevcut nesnelerin mutasyonunun neden olduğu sürprizler olmadan yakın modülü oluşturdum ( daha fazla bilgi için belgelere bakın ).

2018 Güncellemesi

Bugün , Moment yerine tarih / saat manipülasyonu için Luxon'u kullanmanızı öneririm ( Moment'in aksine) tüm nesneleri değişmez hale getirir, böylece tarihlerin örtük mutasyonu ile ilgili kötü sürprizler olmaz.

Daha fazla bilgi

Ayrıca bakınız:

Rob Gravelle tarafından JavaScript tarih ayrıştırma kitaplıkları hakkında bir dizi makale:

Sonuç olarak

Tabii ki herkes tekerleği yeniden icat etmeye çalışabilir, düzenli bir ifade yazabilir (ancak bunu yapmadan önce lütfen ISO 8601 ve RFC 3339'u okuyun) ya da buit hata yapıcılarını 'Invalid Date'(Bu mesajın aynen tüm platformlarda? tüm bölgelerde ise? gelecekte?) veya bir test çözümü kullanın ve onu geliştirmek için zaman kullanabilirsiniz, bunu yeniden icat değil. Burada listelenen tüm kütüphaneler açık kaynak kodlu, özgür yazılımdır.


4
Bunu tam olarak nasıl kullanmalıyım? moment("whatever 123").isValid()döner true.
krivar

4
@krivar Bunu kullanmak en iyisidir: moment("06/22/2015", "DD/MM/YYYY", true).isValid();beklenen tarih biçimi açıkça belirtilmiş ve truesıkı denetim anlamına gelen bir argümanla . Cevabımı daha fazla bilgi ve daha iyi örneklerle güncelledim.
rsp

2
Yine de, ama kullanıcı girişini
onaylıyorum

3
@ JanVanderHaegen 3/4/5 geçerli bir tarih olduğu ve 1 Nisan 2015 olduğu varsayımları yapılabilirse, bu biçimleri (ve potansiyel olarak çok daha fazlasını) açık bir desteklenen biçimler listesine eklemenizi tavsiye ederim. Belirttiğiniz 3/4/5 öğesinin açık bir biçim olmadan belirsiz olduğunu unutmayın.
rsp

3
Bu SO üzerinde gördüğüm en iyi ve en iyi muhafaza cevap olabilir
Phil3992

63

Şu anda üzerinde çalıştığım bir uygulamada bu sorunu nasıl çözdüm:

krillgar'ın geri bildirimlerine dayanarak güncellendi:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}

5
Düğüm için (yeni Tarih (tarih)) .String ()! == "Geçersiz Tarih" i döndürmem gerekiyordu. Ayrıca dikkat edin? true: yanlış gereksizdir. sadece ifadeyi döndürmek burada yeterli olacaktır.
domenukk

IE8'de new Date(date)size 'Geçersiz Tarih' vermez.
krillgar

13
Bu iyi bir cevap değil. new Date(date) !== "Invalid Date"olacak hep dönmek gerçek sol ifadesi bir TIMEVALUE ile bir Date nesnesi döndürür beri NaN olamaz, ===bir dizeye. ==Tür dönüşümü nedeniyle "çalışıyor" kullanılması . Ancak tarih dizelerinin ayrıştırılması hala büyük ölçüde uygulamaya bağlı olduğundan, rastgele biçimleri ayrıştırmak için ona ciddi şekilde kusurluyuz.
RobG

4
yeni Tarih ("469") sonuçları 01 Ocak 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana

3
Bu yanlış kabul edilen doğru cevaba benzer. isDate('Mac OS X 10.14.2')burada true değerini döndürür.
BradStell

24

new Date(date) === 'Invalid Date'yalnızca Firefox ve Chrome'da çalışır. IE8 (test amacıyla makinemde sahip olduğum) NaN veriyor.

Kabul edilen cevaba belirtildiği gibi, Date.parse(date)sayılar için de çalışacaktır. Bunu aşmak için, bunun bir sayı olmadığını da kontrol edebilirsiniz (eğer bu onaylamak istediğiniz bir şeyse).

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

2
Bunun birkaç yıl sonra farkındayım ama isNanbir işlev değil; ilk etapta yanlış durum.
Tim Lewis,

Çalışmıyor. Eğer dateöyleyse Foostreet 1, durumunuz doğru olarak değerlendirilir.
Fabian Picone

9

Böyle bir şeye ne dersin? Bir Date nesnesi mi yoksa bir tarih dizesi mi olduğunu test eder:

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

Bu ISO biçimlendirilmiş dizeleri test değil, ancak RegExp için biraz daha fazla çalışma ile iyi olması gerektiğini belirtmek gerekir.


7

Buradaki yanıtların hiçbiri, 31 Şubat gibi tarihin geçersiz olup olmadığını kontrol etmiyor. Bu işlev, döndürülen ayın orijinal aya eşit olup olmadığını kontrol ederek ve geçerli bir yılın sunulduğundan emin olarak ele almaz.

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

Çünkü soru, bir dizenin 'geçerli' bir tarih olup olmadığını kontrol etmek değil, sadece bir dizenin bir tarih formatını temsil edip etmediğini kontrol etmek.
Thizzer

@ Thizzer iyi bir nokta. Düzeltmeyi umursamıyorum ama sorunuzu yeniden okurken, 10'un doğrulanmaması gerektiğini, ancak zaman damgalarına izin verilmesi gerektiğini söylediğiniz için üzüldüm.
ykay diyor Reinstate Monica

xD bunu fark etmedi bile, önceki günlerimden bir tarih / zaman damgası olan bir soru. Soruyu bugün daha sonra düzenlemeye çalışacağım.
Thizzer

neden ay-1 sonra ay + 1?
Kapil Raghuwanshi

@KapilRaghuwanshi javascript tarihleri ​​sıfır tabanlı bir ay kullanır, bu nedenle uygun tarihi oluşturmak için 1'i
çıkarmanız

5

Doğrulamak için Normal ifadeyi kullanın.

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

4

Yukarıdaki tüm yorumlara atıfta bulunarak, bir çözüm buldum.

Bu, Dategeçirilen ISO biçimindeyse veya diğer biçimler için işlem yapılması gerektiğinde çalışır .

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

Burada JSFiddle'da oynayabilirsiniz .


1
Uygulamamın desteklediği tarih dizeleri biçiminde YYYY-MM-DDolduğundan T00:00:00.000Zbu çözüm benim için en iyi sonucu verdi , bu nedenle geçerli dizeleri kontrol etmek için bu çözümü eklemek ve kullanmak önemsizdir .
hızlandırın

javascript için bu çalışıyor, ama daktiloda nasıl kullanılır.?
Sae

3

İşte sadece kullanan gelişmiş bir fonksiyon Date.parse():

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

Not: Date.parse () sayıları ayrıştırır: örneğin Date.parse(1)bir tarih döndürür. Burada sbir sayı olup olmadığını, tarih olup olmadığını kontrol ediyoruz .


1
bu 'test 2' geçerken gerçek bir tarih olarak geçeceğinden çalışmaz. kromun en son sürümünde test edilmiştir
user1751287

2

Bunu yapardım

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

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

Burada oyna


2
Bu, mevcut Chrome'da, muhtemelen diğer tarayıcılarda çalışmaz. Sağlanan dize değiştirdim ve EXAMPLE STRING 12345"Geçerli tarih" döndürür.

1

İşte minimalist bir versiyon.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}

1
Örneğim için hala çalışmıyor:isDate("  1")
Tomas

@Tom Tarih olup olmadığını belirlemeden önce değerin boşluk karakteri içerip içermediğini kontrol etmelisiniz. Sorununuz, denetleyici mantığınız tarafından ele alınması gereken özel bir durumdur.
Bay Polywhirl

1
1 Ocak 2020 dizesi beyaz boşluk içeren geçerli bir tarih olduğundan beyaz boşluk karakterlerinin denetlenmesi gerekmez. Metodunuz bunu hesaba katmıyor.
Kirstin Walsh

1

Bu çağrılabilir işlev mükemmel çalışır, geçerli tarih için true değerini döndürür. ISO biçiminde bir tarih kullanarak arama yaptığınızdan emin olun (yyyy-aa-gg veya yyyy / aa / gg):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}

1
Güzel, ama soruyu tamamen cevaplamıyor. Özellikle, verilen örneklerden biri olan '2009-11-10T07: 00: 00 + 0000' için çalışmaz.
amadan

Bunun doğrulanması gerektiği gibi çalıştığını düşünmeyin TARİH ('2016-12-30T08: 00: 00.000Z') // yanlış
Jose Browne

Bunun işe yarayıp yaramadığına bakılmaksızın, basitleştirilebilirreturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung

1

Eski bir soru olduğunu biliyorum ama aynı sorunla karşılaştım ve cevapların hiçbirinin düzgün çalışmadığını gördüm - özellikle orijinal soru olan tarihlerden sayıları (1.200.345, vb.) Ayıklamak. İşte aklıma gelen oldukça alışılmışın dışında bir yöntem ve işe yarıyor gibi görünüyor. Lütfen başarısız olacağı durumlar olup olmadığını belirtin.

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

Bu, sayıları ayıklamak için kullanılan satırdır. Böylece, tüm fonksiyon şöyle görünebilir:

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


1
console.log("hello 1 ", isDate("hello 1 "));döner
John

Haklısın! bir çözümün var mı? Şimdiye kadar buradaki cevapların hiçbirinin soruyu uygun şekilde ele almadığını düşünüyorum!
peekolo

"% 100", yüzde, true
değerini

0

nesnenin bir Date nesnesi olup olmadığını bulması için Date ile ilgili bir işlev olup olmadığını kontrol etmek uygun mudur?

sevmek

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

0

Sonunda böyle yapıyorum. Bu tüm formatları kapsamaz. Buna göre ayar yapmak zorundasınız. Biçim üzerinde kontrolüm var, bu yüzden benim için çalışıyor

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

-1

Tamam, bu eski bir soru, ama buradaki çözümleri kontrol ederken başka bir çözüm buldum. Benim için getTime () fonksiyonunun date nesnesinde mevcut olup olmadığını kontrol etmek için çalışır:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}

-1

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

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/dayjs@1.8.21/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>

Bir hafif kütüphane sizin için hazırdır: Day.js


1
Bu temel olarak StackOverflow reklamı, bunu yapmaktan kaçının.
c4sh

-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Varsayılan olarak bu DOĞRU olarak ayarlıdır. Böylece yanlış biçimli dizeler bile iyi değerler döndürür.

Ben böyle bir şey kullandım:

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

5
... javascript ?!
artparks

-5

Bunu dene:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}

6
Bu benim için işe yaramıyor. İlk olarak koşuldaki değişken ayrıştırılmaz, ancak bunu kaldırır ve böyle bir şey denerseniz: if (date = new Date ("rubbish")) {alert (date); } Tarih çöp olsa bile, Tarih işlevi "Geçersiz Tarih" (en azından firefox'ta) döndüreceği için uyarı yine de yürütülür, böylece koşul doğru olarak değerlendirilir. Bazı tarayıcılar geçersiz tarihte null döndürürse, o tarayıcılarda çalışır. Burada tarayıcı tutarsızlığı olabilir.
Cloudranger
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.