Doszedłem do wniosku, że problem był spowodowany time_zone
mojego serwera MySQL ustawienie ustawione na SYSTEM
(a mój system to US Central). Laravel dostarcza znaczniki czasu, które zostały już przekonwertowane na UTC, ale moja baza danych interpretuje je jako US Central ze względu na time_zone
ustawienie. Czasy faktycznie się zmieniają ponownie wewnętrznie przez MySQL do „prawdziwej” reprezentacji znacznika czasu UTC unix (która będzie niepoprawna, ponieważ jest przesunięta o strefę czasową), nawet jeśli wydaje się, że w każdym zapytaniu jest to UTC, ponieważ są one również ponownie konwertowane do US Central w celu odczytu ( Wiem dobrze).
Z tego powodu o godzinie 20:00:39 (20:00) czasu lokalnego moje znaczniki czasu Laravel UTC to 02:00:39. MySQL interpretuje te czasy jako czas centralny Stanów Zjednoczonych, a ponieważ jest to czas między 02:00 a 03:00 (czyli wtedy, gdy zegary przeskakują do przodu w przypadku US Central), czas jest nieprawidłowy.
Najlepszym rozwiązaniem dla aplikacji Laravel jest wymuszenie na każdym połączeniu z bazą danych użycia +00:00
strefa czasowa (lub cokolwiek ustawiłeś jako strefę czasową aplikacji w config/app.php
), aby nie nastąpiła wtórna konwersja. Można to zrobić w config/database.php
:
'mysql' => [
// ...
'timezone' => '+00:00'
],
W ten sposób nie jesteś zdany na łaskę serwera bazy danych, jeśli ma skonfigurowaną strefę czasową inną niż twoja aplikacja Laravel. Inną opcją jest zmiana time_zone
bazy danych ustawienie, ale nadal ryzykujesz powtórzenie się błędu, jeśli kiedykolwiek zmienisz hosty lub będziesz musiał przebudować serwer z jakiegokolwiek powodu (i nie skonfigurujesz ponownie strefy czasowej poprawnie) lub wpłyniesz na inne bazy danych na serwerze.
Ważna uwaga:Ponieważ wszystkie poprzednie znaczniki czasowe były wewnętrznie przesunięte przez MySQL ze skonfigurowanej strefy czasowej do znaczników czasowych UTC (co znowu było błędne, ponieważ rekordy były już w czasie UTC), może być konieczne przeprowadzenie migracji danych w celu poprawienia stare znaczniki czasu. Nie badałem dalej, ponieważ dla mojej aplikacji nie ma znaczenia, czy stare znaczniki czasu były błędne o kilka godzin.