Otrzymuję ciąg daty od interfejsu API, który jest sformatowany jako yyyy-mm-dd
.
Obecnie używam wyrażenia regularnego do sprawdzania poprawności formatu ciągu, co działa dobrze, ale widzę przypadki, w których może to być poprawny format zgodny z ciągiem, ale w rzeczywistości niepoprawna data. tj. 2013-13-01
na przykład.
Czy jest lepszy sposób na PHP, aby wziąć taki ciąg znaków 2013-13-01
i powiedzieć, czy jest to poprawna data dla formatu yyyy-mm-dd
?
Odpowiedzi:
Możesz użyć
DateTime
klasy w tym celu:[ Funkcja zaczerpnięta z tej odpowiedzi . Również na php.net . Pierwotnie napisany przez Glavić . ]
Przypadki testowe:
Próbny!
źródło
strtotime
aby uzyskać uniksowy znacznik czasu, a następniedate('Y-m-d', $t)
uzyskać datę ciągu. Następnie porównujesz je tak jak w tej odpowiedzi.strtotime
, ale w przypadku niestandardowych formatów, którestrtotime
nie rozpoznają, będziesz potrzebować innego rozwiązania. A dla wersji PHP 5.2 wsparcie zatrzymane w styczniu 2011, dla 5.3 wsparcie zatrzymane w sierpniu 2014.var_dump( validateDate('2012-2-9'));
'Y-n-j'
postać @reignsly.$d
nie będzie to fałszywe, jeśli podasz datę, która ma przepełnione części, na przykład 13 miesiąc (2013-13-01). Ale to naprawdę zależy od tego, czego chcesz. Jeśli chcesz na przykładvalidateDate('2015-55-66')
być poprawny, to tak, musisz tylko sprawdzić, czy$d
jest obiektem, czy nie.Sprawdź, czy jakikolwiek ciąg jest datą
źródło
yyyy-mm-dd
.2015-02-30
za prawidłową datę, ponieważ gdy podany dzień jest większy niż liczba dni w danym miesiącu (lub ujemna) php przechodzi na następny miesiąc. Ponieważ gwarantowana jest data w formacie,yyyy-mm-dd
można to naprawić, zmieniając wartość powrotu nareturn (bool)strtotime($myDateString) && date("Y-m-d", strtotime($myDateString)) == $myDateString;
.(bool)strtotime('s')
okazuje się to prawdą?$myDateString = str_replace("/", '-', $myDateString);
przed powrotem, jeśli ciąg daty zawiera ukośniki (/), takie jak: - dd / mm / rrrrUżywaj w prosty sposób z wbudowaną funkcją php:
Test
źródło
if
celu zwróceniatrue
lub po prostufalse
zwróć test.return sizeof($tmpDate) == 3 && checkdate($tmpDate[1]...
2
,20
,202
,2020
lub nawet jeśli rok jest20201
- to prawda powraca za każdym razem.Sprawdź, czy ciąg znaków jest datą, nawet jeśli ciąg znaków jest niestandardowy
(strtotime nie akceptuje żadnego niestandardowego formatu)
źródło
if
celu zwróceniatrue
lub po prostufalse
zwróć test.Ta opcja jest nie tylko prosta, ale także akceptuje prawie każdy format, chociaż w niestandardowych formatach może być wadliwa.
źródło
202
zwraca liczbę ujemną - która nadal przechodzi test.Możesz także przeanalizować datę dla daty miesiąca i roku, a następnie możesz użyć funkcji PHP, o
checkdate()
której możesz przeczytać tutaj: http://php.net/manual/en/function.checkdate.phpMożesz także wypróbować ten:
źródło
Najłatwiejszym sposobem sprawdzenia, czy podana data jest poprawna, jest prawdopodobnie konwersja jej na unikstime przy użyciu
strtotime
, sformatowanie jej do formatu podanej daty, a następnie porównanie:function isValidDate($date) { return date('Y-m-d', strtotime($date)) === $date; }
Oczywiście możesz użyć wyrażenia regularnego, aby sprawdzić poprawność, ale będzie on ograniczony do danego formatu, za każdym razem będziesz musiał go edytować, aby spełnić inne formaty, a także będzie więcej niż wymagany. Wbudowane funkcje to najlepszy sposób (w większości przypadków) na uzyskanie pracy.
źródło
checkdate()
- ale okazuje się, że data checkdate kończy się niepowodzeniem, jeśli rok ma DOWOLNĄ wartość:2, 20, 202, 2020, 20201
- wszystkie zwracają wartość true. Idę z twoim rozwiązaniem!Zgodnie z odpowiedzią cl-sah, ale brzmi to lepiej, krócej ...
Test
źródło
count($tempDate) === 3
chociażMam tę rzecz, że nawet w PHP lubię znaleźć funkcjonalne rozwiązania. Na przykład odpowiedź udzielona przez @migli jest naprawdę dobra, bardzo elastyczna i elegancka.
Ale ma problem: co zrobić, jeśli trzeba zweryfikować wiele ciągów DateTime w tym samym formacie? Będziesz musiał powtórzyć format w dowolnym miejscu, co jest sprzeczne z zasadą SUCHOŚCI . Moglibyśmy ustawić format na stały, ale nadal musielibyśmy przekazać stałą jako argument do każdego wywołania funkcji.
Ale nie bój się więcej! Możemy użyć curry na ratunek! PHP nie sprawia, że to zadanie jest przyjemne, ale nadal można wdrożyć curry z PHP:
Więc co właśnie zrobiliśmy? Zasadniczo zawinęliśmy ciało funkcji w anonimowy i zamiast tego zwróciliśmy taką funkcję. Możemy wywołać funkcję sprawdzania poprawności w następujący sposób:
Tak, niezbyt duża różnica ... ale prawdziwa moc pochodzi z częściowo zastosowanej funkcji , możliwej dzięki curry:
Programowanie funkcjonalne FTW!
źródło
Obawiam się, że większość głosów ( https://stackoverflow.com/a/19271434/3283279 ) nie działa poprawnie. Czwarty przypadek testowy (var_dump (validateDate ('2012-2-25')); // false) jest niepoprawny. Data jest poprawna, ponieważ odpowiada formatowi - m pozwala na miesiąc z zerowym początkiem lub bez (patrz: http://php.net/manual/en/datetime.createfromformat.php ). Dlatego data 2012-2-25 ma format Ymd, a przypadek testowy musi być prawdziwy, a nie fałszywy.
Uważam, że lepszym rozwiązaniem jest przetestowanie możliwego błędu w następujący sposób:
źródło
Co powiesz na ten?
Po prostu używamy bloku try-catch.
To podejście nie ogranicza się tylko do jednego formatu daty / godziny i nie trzeba definiować żadnej funkcji.
źródło
'0000-00-00 00:00:00'
jest prawidłową wartością daty i godziny . To tylko pierwsza wartość. Jednak właściwość date obiektu datetime będzie mieć wartość'-0001-11-30 00:00:00'
.Testowane rozwiązanie Regex:
Zwróci wartość null, jeśli data jest niepoprawna lub nie ma formatu rrrr-mm-dd, w przeciwnym razie zwróci datę.
źródło
Sprawdź poprawność za pomocą funkcji checkdate :
źródło
źródło
źródło
Wypróbuj to:
źródło