2009-02-28 16 views
8

Użytkownicy wybierają datę z 3 list (dzień, miesiąc, rok). Połączę je po stronie serwera, tworząc ciąg znaków typu "2008-12-30". W jaki sposób mogę następnie sprawdzić poprawność, aby upewnić się, że ta data jest w odpowiednim formacie/tylko numerycznym, itp?Jak sprawdzić poprawność daty MYSQL w PHP?

+0

Czy możesz to zmienić nieco; nie jest całkiem jasne, o co prosisz. Czy chcesz sprawdzić datę przychodzącą z zapytania, czy też chcesz sprawdzić poprawność poszczególnych składników przed wstawieniem ich do bazy danych? – Rob

+0

Chcę połączyć składniki daty i sprawdzić połączoną datę z bazą danych. –

+1

Dlaczego zostało to odrzucone? –

Odpowiedz

6

Jeśli są to 3 osobne listy rozwijane, należy je zweryfikować jako trzy oddzielne wartości.

Tj

  • potwierdzić, że kolumna roku jest numeryczne i między co roku obowiązują w swojej aplikacji
  • potwierdzić, że kolumna miesięcy jest numeryczny
  • potwierdzić, że kolumna dzień jest numeryczny
  • Sprawdź, czy wszystkie są poprawnymi wartościami, używając checkdate()

Lub możesz po prostu je rzucić l do liczby całkowitej, połącz je razem w datę i sprawdź, czy wynikowa data jest prawidłowa. Tj

$time = mktime(0, 0, 0, (int)$_POST['month'], (int)$_POST['day'], (int)$_POST['year']); 

// in this example, valid values are between jan 1 2000 (server time) and now 
// modify as required 
if ($time < mktime(0, 0, 0, 1, 1, 2000) || $time > time()) 
    return 'Invalid!'; 

$mysqltime = date('Y-m-d', $time); 

// now insert $mysqltime into database 

Wadą tej metody jest to, że będzie ona działać tylko z datami w zakresie Unix timestamp IE 1970 do 2038 lub tak.

+0

Prawdopodobnie chcesz sprawdzić, czy jest to liczba całkowita, a nie numeryczna. is_numeric ma wartość true dla zmiennych typu floats oraz liczb całkowitych, ale is_int sprawdza tylko liczby całkowite. – gpojd

+0

is_int() nie może działać na zmiennych przesłanych przez użytkownika, tj. Zmiennych w $ _POST, ponieważ są one zawsze typu string. Możesz jednak rzucić je na liczbę całkowitą za pomocą (int) $ _ POST ['var'], a następnie luźno porównać z oryginalną wartością ciągu (używając ==). – thomasrutter

2

Możesz sprawdzić, czy data jest ważna, używając checkdate. Jeśli chcesz się upewnić, że wartości są numeryczne i mają prawidłową długość, możesz zrobić coś tak prostego, jak kombinacja przed utworzeniem daty.

// untested 
if(!ctype_digit)($month) || strlen($month) != 2) { 
    // handle error 
} 
// repeat for $day and $year 
if (checkdate($month, $day, $year) { 
    // do your work 
} 
+0

Zmieniłem swoją odpowiedź z is_int na ctype_digit na podstawie komentarza thomasruttera, że ​​is_int nie będzie poprawnie obsługiwać zmiennych POST. – gpojd

-1

Jeśli masz trzy listy rozwijane, wartości pochodzące z list rozwijanych powinny zawsze być liczbami, ponieważ kontrolujesz wartości powiązane z danym miesiącem (pokazane poniżej). Doprowadziłoby to do wniosku, że połączony wynik jest prawidłowy.

<option value="01">January</option> 

Jeśli podasz zapewnić wpisy pomoc w upadków spadek takie jak „Wybierz miesiąc”, a następnie można dokonać tej wartości 0 i zapewniają, że wartości pochodzące z każdej skrzynce jest większa niż zero.

Istnieje możliwość, że ktoś zmieni formularz HTML w celu podania innych wartości. Jeśli jest to problemem, możesz użyć funkcji PHP ctype_digit(), aby sprawdzić, czy każda podana wartość jest rzeczywiście cyfrą.

Jeśli niepokoisz się, że data jest rzeczywiście ważna, użyj funkcji checkdate().

+0

Umożliwia wysyłanie postów do skryptu bez użycia formularzy. Potrafię napisać bota, który wysyła post do formularza i publikuje dowolną wartość, którą wpisuję dla każdego pola bez użycia formularzy. –

+0

To prawda, dlatego sugestia użycia ctype_digit() i checkdate() ma sens. Opierałem swoją odpowiedź na stwierdzeniu, że masz formularz. Nawet jeśli używasz skryptu, w tym przypadku nie ma wielu przypadków, w których nie użyłby on wartości w formularzach. – Paulo

1

Po prostu miałem ten sam problem. Napisałem krótki funkcję, która sprawdza, czy format jest poprawny, a także jeżeli data jest prawdziwa:

function valid_mysql_date($str){ 
    $date_parts = explode('-',$str); 
    if (count($date_parts) != 3) return false; 
    if ((strlen($date_parts[0]) != 4) || (!is_numeric($date_parts[0]))) return false; 
    if ((strlen($date_parts[1]) != 2) || (!is_numeric($date_parts[1]))) return false; 
    if ((strlen($date_parts[2]) != 2) || (!is_numeric($date_parts[2]))) return false; 
    if (!checkdate($date_parts[1], $date_parts[2] , $date_parts[0])) return false; 
    return true; 
} 

nadzieję, że to pomaga.

+1

jest checkdate(), koleś –

+0

zabawny, teraz staram się zrozumieć, co jest ze mną nie tak ... :) –

+0

ok teraz widzę co miałem na myśli, bo właśnie wpadłem na ten sam problem dzisiaj. checkdate() pyta o trzy parametry. więc jeśli masz ciąg daty, to ci to nie pomaga. moja funkcja pobiera ciąg znaków i formatuje go i sprawdza przy pomocy checkdate() –

17

ja osobiście uważam, że jest to prawidłowe i elegancki sposób, aby ustalić, czy data jest zarówno według formatu i ważnego:

  • traktuje terminy takie jak 20111-03-21 za nieważne - w przeciwieństwie checkdate()
  • brak możliwych ostrzeżeń PHP (jeśli oczywiście podano jeden parametr) - w przeciwieństwie do większości rozwiązań explode()
  • wykonuje skok rok uwzględnieniu przeciwieństwie do rozwiązań regex tylko
  • w pełni kompatybilne z DATE formacie mysql (10.03.21 jest taka sama jak 2010-03-21)

Oto sposób można użyć:

/** 
* Tests if a string is a valid mysql date. 
* 
* @param string date to check 
* @return boolean 
*/ 
function validateMysqlDate($date) 
{ 
    return preg_match('#^(?P<year>\d{2}|\d{4})([- /.])(?P<month>\d{1,2})\2(?P<day>\d{1,2})$#', $date, $matches) 
      && checkdate($matches['month'],$matches['day'],$matches['year']); 
} 
+0

Tak, $ str powinien zostać zmieniony na $ date ... [funkcja edytowana] – Ricky

+0

Dzięki, w jakiś sposób ta, której używam w produkcji jest poprawna, przepraszam za błąd. – raveren

+0

Dobrze! to jest pomocne –

4

używam tej funkcji:

<?php 
function validateMysqlDate($date){ 
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $date, $matches)) { 
     if (checkdate($matches[2], $matches[3], $matches[1])) { 
      return true; 
     } 
    } 
    return false; 
} 

// check it: 
    $a = validateMysqlDate('2012-12-09 09:04:00'); 
    $b = validateMysqlDate('20122-12-09 09:04:00'); 
    $c = validateMysqlDate('2012-12_09 09:04:00'); 
    $d = validateMysqlDate(''); 
    var_dump($a); 
    var_dump($b); 
    var_dump($c); 
    var_dump($d); 
?> 

$ a jest prawdziwe, inne są fałszywe - i tha t jest poprawna

Funkcja z Raveren (powyżej) nie będzie zawierać ważnych dat z sygnaturami czasowymi !!! $ a false tam jest! I przy okazji: checkdate() zwróci wartość true dla $ b, chociaż nie jest to poprawna datetime mysql

+0

Dzięki, twoja funkcja mi pomogła :) –

+0

To będzie * niepoprawnie * unieważniło '10.03.21 00: 00: 00' i nie będzie zatwierdzać ciągów daty bez czasu * w ogóle * - o co poprosił PO. – raveren

Powiązane problemy