Tôi đã phát hiện ra rằng sự cố là do time_zone
của máy chủ MySQL của tôi cài đặt đang được đặt thành SYSTEM
(và hệ thống của tôi là Trung tâm Hoa Kỳ). Laravel đang cung cấp dấu thời gian đã được chuyển đổi sang UTC, nhưng cơ sở dữ liệu của tôi đang hiểu chúng là Trung tâm Hoa Kỳ do time_zone
thiết lập. Thời gian thực sự đang được chuyển đổi một lần nữa nội bộ bởi MySQL thành biểu diễn dấu thời gian unix UTC "thực" (sẽ không chính xác vì nó bị lệch bởi múi giờ), mặc dù chúng dường như đã là UTC trong mọi truy vấn vì chúng cũng được chuyển đổi trở lại Trung tâm Hoa Kỳ để đọc ( Tôi biết đúng).
Do đó, lúc 20:00:39 (8:00 tối) giờ địa phương, dấu thời gian UTC Laravel của tôi là 02:00:39. MySQL hiểu những thời điểm này là giờ Trung tâm Hoa Kỳ và vì thời gian nằm trong khoảng từ 02:00 đến 03:00 (đó là khi đồng hồ chuyển tiếp về phía trước đối với Trung tâm Hoa Kỳ) nên thời gian không hợp lệ.
Giải pháp tốt nhất cho ứng dụng Laravel là buộc mọi kết nối cơ sở dữ liệu phải sử dụng +00:00
múi giờ (hoặc bất cứ thứ gì bạn đã đặt làm múi giờ ứng dụng trong config/app.php
) vì vậy sẽ không có chuyển đổi thứ cấp xảy ra. Điều này có thể được thực hiện trong config/database.php
:
'mysql' => [
// ...
'timezone' => '+00:00'
],
Bằng cách này, bạn không phải lo máy chủ cơ sở dữ liệu của mình nếu nó có múi giờ được định cấu hình khác với ứng dụng Laravel của bạn. Tùy chọn khác là thay đổi time_zone
của cơ sở dữ liệu nhưng sau đó bạn vẫn có nguy cơ tái diễn lỗi nếu bạn thay đổi máy chủ hoặc cần xây dựng lại máy chủ vì bất kỳ lý do gì (và không định cấu hình lại múi giờ chính xác) hoặc ảnh hưởng đến các cơ sở dữ liệu khác trên máy chủ.
Lưu ý quan trọng:Vì tất cả các dấu thời gian trước đó đang được bù đắp nội bộ bởi MySQL từ múi giờ đã định cấu hình thành dấu thời gian unix UTC (một lần nữa, sai vì các bản ghi đã là UTC) nên có thể cần phải chạy di chuyển dữ liệu để sửa lỗi dấu thời gian cũ. Tôi chưa điều tra thêm vì đối với ứng dụng của tôi, không quan trọng nếu dấu thời gian cũ bị sai vài giờ.