Tôi đã tìm ra nó cho mục đích của tôi. Tôi sẽ tóm tắt những gì tôi đã học được (xin lỗi, những ghi chú này dài dòng; chúng cũng dành cho người giới thiệu trong tương lai của tôi như bất cứ điều gì khác).
Trái với những gì tôi đã nói trong một trong những bình luận trước đây của tôi, DATETIME và dấu thời gian lĩnh vực làm hành xử khác nhau. Các trường TIMESTAMP (như tài liệu chỉ ra) lấy bất cứ thứ gì bạn gửi cho chúng ở định dạng "YYYY-MM-DD hh: mm: ss" và chuyển đổi nó từ múi giờ hiện tại của bạn sang giờ UTC. Điều ngược lại xảy ra một cách minh bạch bất cứ khi nào bạn lấy dữ liệu. Các trường DATETIME không thực hiện chuyển đổi này. Họ lấy bất cứ thứ gì bạn gửi cho họ và chỉ cần lưu trữ trực tiếp.
Cả hai loại trường DATETIME và TIMESTAMP đều không thể lưu trữ chính xác dữ liệu trong múi giờ quan sát DST . Nếu bạn lưu trữ "2009-11-01 01:30:00", các trường không có cách nào để phân biệt phiên bản 1:30 sáng mà bạn muốn - phiên bản -04: 00 hoặc -05: 00.
Được, vì vậy chúng tôi phải lưu trữ dữ liệu của mình ở múi giờ không phải DST (chẳng hạn như UTC). Các trường TIMESTAMP không thể xử lý chính xác dữ liệu này vì những lý do tôi sẽ giải thích: nếu hệ thống của bạn được đặt thành múi giờ DST thì những gì bạn đưa vào TIMESTAMP có thể không phải là thứ bạn lấy lại được. Ngay cả khi bạn gửi cho nó dữ liệu mà bạn đã chuyển đổi sang UTC, nó vẫn sẽ giả định là dữ liệu trong múi giờ địa phương của bạn và thực hiện một chuyển đổi khác sang UTC. Vòng quay từ địa phương đến UTC-trở lại địa phương do TIMESTAMP thực thi này sẽ bị mất khi múi giờ địa phương của bạn quan sát DST (kể từ "2009-11-01 01:30:00" ánh xạ đến 2 thời điểm khác nhau có thể xảy ra).
Với DATETIME, bạn có thể lưu trữ dữ liệu của mình ở bất kỳ múi giờ nào bạn muốn và tự tin rằng bạn sẽ nhận lại được bất kỳ thứ gì bạn gửi (bạn không bị buộc phải chuyển đổi khứ hồi mất mát mà các trường TIMESTAMP cung cấp cho bạn). Vì vậy, giải pháp là sử dụng trường DATETIME và trước khi lưu vào trường, hãy chuyển đổi từ múi giờ hệ thống của bạn thành bất kỳ múi giờ không phải DST nào mà bạn muốn lưu (tôi nghĩ UTC có lẽ là lựa chọn tốt nhất). Điều này cho phép bạn xây dựng logic chuyển đổi thành ngôn ngữ kịch bản của mình để bạn có thể lưu rõ ràng UTC tương đương với "2009-11-01 01:30:00 -04: 00" hoặc "" 2009-11-01 01:30: 00-05: 00 ”.
Một điều quan trọng khác cần lưu ý là các hàm toán học ngày / giờ của MySQL không hoạt động đúng xung quanh ranh giới DST nếu bạn lưu trữ ngày tháng của mình trong DST TZ. Vì vậy, tất cả các lý do hơn để tiết kiệm trong UTC.
Tóm lại, bây giờ tôi làm điều này:
Khi truy xuất dữ liệu từ cơ sở dữ liệu:
Diễn giải rõ ràng dữ liệu từ cơ sở dữ liệu dưới dạng UTC bên ngoài MySQL để có được dấu thời gian Unix chính xác. Tôi sử dụng hàm strtotime () của PHP hoặc lớp DateTime của nó cho việc này. Nó không thể được thực hiện một cách đáng tin cậy bên trong MySQL bằng cách sử dụng các hàm CONVERT_TZ () hoặc UNIX_TIMESTAMP () của MySQL vì CONVERT_TZ sẽ chỉ xuất ra giá trị 'YYYY-MM-DD hh: mm: ss' gặp phải vấn đề không rõ ràng và UNIX_TIMESTAMP () giả định giá trị của nó đầu vào nằm trong múi giờ hệ thống, không phải múi giờ mà dữ liệu THỰC SỰ được lưu trữ trong (UTC).
Khi lưu trữ dữ liệu vào cơ sở dữ liệu:
Chuyển đổi ngày của bạn thành thời gian UTC chính xác mà bạn mong muốn bên ngoài MySQL. Ví dụ: với lớp DateTime của PHP, bạn có thể chỉ định "2009-11-01 1:30:00 EST" khác biệt với "2009-11-01 1:30:00 EDT", sau đó chuyển nó thành UTC và lưu thời gian UTC chính xác vào trường DATETIME của bạn.
Phù. Cảm ơn rất nhiều vì sự đóng góp và giúp đỡ của mọi người. Hy vọng rằng điều này sẽ giúp ai đó bớt đau đầu trên đường.
BTW, tôi thấy điều này trên MySQL 5.0.22 và 5.0.27