2017-05-31 72 views
5

Dzisiaj spotkałem się z czymś zagmatwalym dla zachowania funkcji \DateTime::createFromFormat.PHP DateTime :: createFromFormat behavoiur

W moim przypadku mam ciąg znaków, reprezentujący datę w następującym formacie: m/Y (05/2017). Kiedy chcę przekonwertować ciąg do obiektu DateTime Napotkałem następujący problem:

$date = \DateTime::createFromFormat('m/Y', '02/2017');

kiedy zrzucić zmienną $date właściwość data wewnątrz jest '2017-03-03 11:06:36.000000'

Ale jeśli dodać datę przed miesiącem $date = \DateTime::createFromFormat('d/m/Y', '01/02/2017'); otrzymuję obiekt z poprawną właściwością daty. (niestety nie mogę zmienić formatu daty i dodać dnia.) Musi to być m/Y).

Naprawiona przeze mnie poprawka polega na łączeniu pierwszego dnia miesiąca z łańcuchem dat, który mam $date = '01/'.$dateString;, ale nie chcę tego robić, ponieważ jest on zakodowany na stałe.

Co jest nie tak? Czy funkcja createFromFormat nie zawiera informacji o tym, jak utworzyć obiekt? Jestem z tym bardzo zdezorientowany. Dzięki za pomoc wszystkich z góry!

+0

to właśnie tworzy obiekt, var_dump $ Data-> Format() (format jest taka sama jak data, więc RMD nadal obowiązuje etc.) i powinieneś zobaczyć co czekasz :) – ThisGuyHasTwoThumbs

+1

To zapełnia brakuje dane z dzisiejszymi danymi (dzień 31) i dostosowuje, aby pominąć nieprawidłowe daty. Pomocne lub nie, jest jak większość funkcji daty działa w PHP. –

Odpowiedz

7

Domyślnie PHP zapełni brakujące wartości datami z bieżącą datą/czasem; więc

$date = \DateTime::createFromFormat('m/Y', '02/2017'); 

wypełni brakującą wartość dnia z bieżącą datą; a ponieważ 31 lutego to nieważna data, przeniesie się do marca. Podobnie godziny/minuty/sekundy będą uzupełniane brakującymi wartościami czasu na podstawie bieżącego czasu.

Jeśli chcesz wymusić zachowanie zmuszać do początku miesiąca/czas, a następnie zmodyfikować maskę z wiodącym !

$date = \DateTime::createFromFormat('!m/Y', '02/2017'); 

to będzie wypełnić brakujący dzień od 1 miesiąca, i razem 00:00:00

Alternatywnie, końcowe | będzie miała taki sam efekt

$date = \DateTime::createFromFormat('m/Y|', '02/2017'); 
+0

Dziękuję bardzo za odpowiedź. To coś, co poznam po raz kolejny :) – Whiplash

+0

Składnia '!' I '|' są niesamowite i wydają się istnieć przez [dość długi czas] (https://3v4l.org/YvIkt). –

+0

Warto przeczytać [dokładne specyfikacje] (http://php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters), aby zrozumieć, jak działają kody '!' I '|' . Zasadniczo ustawiają wartości w Epoce Unixowej - otrzymujemy dzień 1, ponieważ zdarzyło się to 1 stycznia 1970 00:00:00 UTC. –

0

Nie można przechowywać niekompletnych dat, przynajmniej w dedykowanym formacie daty, który może być używany do złożonych obliczeń daty (nic nie stoi na przeszkodzie, aby utworzyć własną klasę MonthYear).podczas tworzenia DateTime() obiekt z informacją niepełną czymś tak musi się zdarzyć:

  • Wypadek
  • Używaj pewne wartości domyślne

PHP wybiera drugą opcję i podejmuje decyzję odziedziczone z języka C data biblioteka:

  1. Załóżmy, że brakujące dane znaczy "teraz"
  2. Spróbuj rozwiązać aut omatically te nieprawidłowe daty, że algorytm ten może tworzyć

w tym przypadku Feb 2017 staje 31 Feb 2017 (bo „teraz” jest 31 May 2017) i PHP Wynika to rozumowanie: tylko luty miał 28 dni w roku 2017, ale mam jeszcze trzy; użytkownik prawdopodobnie przeniesie te trzy dodatkowe dni do marca. Tak więc 3 Mar 2017.

widzę żadnego powodu, aby uniknąć twarde kodowania 01 bo przecież to jest ciężko zakodowana wartość (dlaczego pierwszy dzień miesiąca i nie ostatni lub inny dzień?).

$input = '05/2017'; 
$date = \DateTime::createFromFormat('d/m/Y', "01/$input"); 
+0

Dziękujemy za szczegółowe wyjaśnienie funkcjonalności! Chodzi o to, że zawsze staram się unikać wartości hardcoding, ale tym razem Wydaje się, że PHP robi to samo. Przypuszczam, że kodowanie "01" jest takie samo jak dodanie "! M/Y", jak wyjaśniono w powyższej odpowiedzi. – Whiplash

+0

Zasadniczo jest. Ale nawet nie wiedziałem, że możesz używać '!' Aż do dzisiaj. –

+0

Mam na myśli to, że odpowiedź Mark Baker zasugerowała użycie '!' I okazuje się, że robi to samo :) Jeszcze raz bardzo dziękuję. – Whiplash