2011-11-11 14 views
36

Powiel możliwe:
Detecting an “invalid date” Date instance in JavaScriptJavaScript wykrywania Aktualny Daty

używałem następujących wykryć poprawną datę:

var text = $('#Date').val(); 
var date = Date.parse(text); 

if (isNaN(date)) { 
     // Invalid date 
} 

Ale okazało się, że Date.parse myśli następujące ważne daty (mm/dd/rrrr)

  • 2/30/2011
  • 11/31/2011

Każdy inny sposób wykryć nieprawidłowe daty, gdy liczba dni przewyższa łączną liczbę dni w miesiącu?

AKTUALIZACJA: Jeszcze większym problemem jest to, że wtyczka sprawdzania poprawności jQuery nie wykrywa tego jako niepoprawnej daty!

ROZWIĄZANIE:

podstawie @ komentarze Guffa za Stworzyłem następującą funkcję do sprawdzania dat:

function validDate(text) { 

    var date = Date.parse(text); 

    if (isNaN(date)) { 
     return false; 
    } 

    var comp = text.split('/'); 

    if (comp.length !== 3) { 
     return false; 
    } 

    var m = parseInt(comp[0], 10); 
    var d = parseInt(comp[1], 10); 
    var y = parseInt(comp[2], 10); 
    var date = new Date(y, m - 1, d); 
    return (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d); 
} 
+3

Date.parse uważa, że ​​nie są one poprawne, ale przekształca je we właściwe daty. Na przykład. '2/30/2011' zakończy się jako' 03/02/2011' – Andreas

+1

po głosowaniu, aby zamknąć jako dupe, zrozumiałem, że podane pytanie jest * nie * identyczne, chociaż jest powiązane. – zzzzBov

+1

Ponieważ potrzebowałem obsługiwać dane wejściowe w wielu lokalizacjach, zaimplementowaliśmy nasz własny parser daty. Jedyny sposób, w jaki wykryliśmy ten błąd, to porównanie ciągu miesiąca, który przeanalizowaliśmy z miesiącem, który pochodzi z wygenerowanej daty. –

Odpowiedz

72

Aby sprawdzić, czy data jest prawidłowa, można przeanalizować komponenty daty, utworzyć z niej obiekt Date i sprawdzić, czy składniki w danych są takie same, jak analizowane składniki. Jeśli utworzysz obiekt Date z kompnentów znajdujących się poza zakresem, wartości przepłyną do następnego/poprzedniego okresu w celu utworzenia prawidłowej daty. Na przykład new Date(2011,0,42) utworzy obiekt zawierający datę 2/11/2011 zamiast 1/42/2011.

Parsując komponenty zamiast pełnej daty, można również obejść problem z różnymi formatami dat. Moja przeglądarka będzie na przykład oczekiwać formatu daty, takiego jak y-m-d, a nie d/m/y.

Przykład:

var text = '2/30/2011'; 
var comp = text.split('/'); 
var m = parseInt(comp[0], 10); 
var d = parseInt(comp[1], 10); 
var y = parseInt(comp[2], 10); 
var date = new Date(y,m-1,d); 
if (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d) { 
    alert('Valid date'); 
} else { 
    alert('Invalid date'); 
} 

Demo: http://jsfiddle.net/Guffa/UeQAK/

+1

Działa to świetnie! Poza tym musisz zmienić date.getDay() na date.getDate(). –

+1

Oto uaktualnione demo: http://jsfiddle.net/zKb6c/ –

+0

@NickOlsen: Dzięki, zaktualizowałem odpowiedź. – Guffa

3

Jeśli format daty jest ustalona jako M/D/YYYY, można ponownie sformatować analizowany datę i zobacz, czy pasuje do danych wejściowych:

var d = new Date(Date.parse(str)) 
return str === (d.getMonth()+1)+'/'+d.getDate()+'/'+d.getYear(); 

Jednak nie będzie tolerować spacji ani liczb zerowych.

Jeśli nie musisz dokładnie zapisywać danych wejściowych użytkownika, możesz po prostu ponownie sformatować datę i udawać, że to jest to, co wpisano.

Ale jeśli nie możesz tego zrobić, osobno przetworzyłbym komponenty używając RegExp, a następnie porównałem je z wartościami z metod Date.

0

można napisać skrypt, aby to zrobić ręcznie:

function checkDate(day, month) { 
    if ((month == 4 || month == 6 || month == 9 || month == 11) && day < 30) { 
     alert("Date is valid") 
    } 
    else if (month == 2 && day <= 28) { 
     alert("Date is valid") 
    } 
    else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day <= 31) { 
     alert("Date is valid") 
    } 
    else { 
     alert("Date is in-valid") 
    } 
} 

Oczywiście, będzie trzeba także coś zwrócić uwagę na skok lat, ale pamiętaj, że każdy rok podzielny przez 4, a nie przez 100, jest rokiem przestępnym, chyba że pierwsze dwie cyfry roku są podzielne przez 4. To powinno być łatwe do uwzględnienia w tym funkcjonować.

+2

w instrukcji '==' not' = '? – user1575921

0

Przykładem jest źle

poprawna jest

if ((month == 4 || month == 6 || month == 9 || month == 11) && day <= 30) 

<= zamiast =

Ale przykładem są świetne!

Powiązane problemy