Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Các trường ngày giờ trong MySQL và thời gian tiết kiệm ánh sáng ban ngày - làm cách nào để tham khảo thêm giờ?

Tôi đã tìm ra nó cho các mục đích của tôi. Tôi sẽ tóm tắt lại 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 ngược với những gì tôi đã nói trong một trong những nhận xét trước đây của mình, trường DATETIME và TIMESTAMP do cư 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 truy xuất 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ả 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ờ tuân theo 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 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-về đị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ạ tới 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 vào các 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 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 vào (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 bình thường 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, càng có nhiều lý do để tiết kiệm trong UTC.

Tóm lại, bây giờ tôi làm việc 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ì mọi người đã đóng góp ý kiến ​​và giúp đỡ. Hy vọng rằng điều này sẽ giúp người khác đỡ đau đầu hơn.

BTW, tôi thấy điều này trên MySQL 5.0.22 và 5.0.27



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để lấy một truy vấn SQL thô, đã biên dịch từ một biểu thức SQLAlchemy?

  2. Android JDBC không hoạt động:ClassNotFoundException trên trình điều khiển

  3. UTF-8:Tổng quát? Thùng rác? Unicode?

  4. Hibernate:Tự động tạo / cập nhật các bảng db dựa trên các lớp thực thể

  5. Quyền truy cập root MySQL từ tất cả các máy chủ