Ho capito che il problema era dovuto al time_zone
del mio server MySQL impostazione impostata su SYSTEM
(e il mio sistema è US Central). Laravel fornisce timestamp che sono già stati convertiti in UTC, ma il mio database li interpreta come US Central a causa del time_zone
collocamento. I tempi vengono effettivamente convertiti di nuovo internamente da MySQL in una rappresentazione di timestamp UTC unix "reale" (che non sarà corretta perché è compensata dal fuso orario), anche se sembrano essere già UTC in ogni query perché vengono anche riconvertiti in US Central nuovamente per la lettura ( lo so bene).
Per questo motivo, alle 20:00:39 (20:00) ora locale i miei timestamp UTC di Laravel sono 02:00:39. MySQL interpreta questi orari come l'ora centrale degli Stati Uniti e poiché l'ora è compresa tra le 02:00 e le 03:00 (che è il momento in cui gli orologi saltano avanti per gli Stati Uniti centrali), l'ora non è valida.
La soluzione migliore per un'applicazione Laravel è forzare ogni connessione al database a utilizzare un +00:00
timezone (o qualsiasi altra cosa tu abbia impostato come fuso orario dell'applicazione in config/app.php
) quindi non si verificherà una conversione secondaria. Questo può essere fatto in config/database.php
:
'mysql' => [
// ...
'timezone' => '+00:00'
],
In questo modo non sei alla mercé del tuo server di database se ha un fuso orario configurato diverso dalla tua applicazione Laravel. L'altra opzione è cambiare il time_zone
del database impostazione, ma rischi comunque che il bug si ripresenti se cambi host o devi ricostruire il server per qualsiasi motivo (e non configurare nuovamente il fuso orario correttamente) o interessare altri database sul server.
Nota importante:poiché tutti i timestamp precedenti venivano compensati internamente da MySQL dal fuso orario configurato ai timestamp unix UTC (che, ancora una volta, erano errati perché i record erano già UTC), potrebbe essere necessario eseguire una migrazione dei dati per correggere il vecchi timestamp. Non ho indagato ulteriormente perché per la mia domanda non importa se i vecchi timestamp fossero sbagliati di qualche ora.