Tôi có một truy vấn dựa trên thời gian dựa trên đường ray có một số hành vi nhạy cảm múi giờ lẻ, mặc dù theo tôi biết tôi đang sử dụng UTC. Tóm lại, các truy vấn này đưa ra câu trả lời khác nhau:Tại sao truy vấn đường ray này hoạt động khác nhau tùy thuộc vào múi giờ?
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours).gmtime]).length
=> 279
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours)]).length
=> 280
đâu DB thực sự có chứa một mô hình tạo ra trong giờ cuối cùng, và tổng số các mô hình là 280. Vì vậy, chỉ truy vấn đầu tiên là đúng.
Tuy nhiên, trong environment.rb tôi có:
config.time_zone = 'UTC'
Các múi giờ hệ thống (theo báo cáo của 'date') là BST (đó là GMT + 1) - vì vậy bằng cách nào đó này gió lên bị coi là UTC và truy vấn vi phạm.
Điều này đang gây ra cho tôi tất cả các vấn đề khi tôi cần tham số truy vấn vào các thời điểm khác nhau cho một hành động (sau đó được chuyển đổi bằng Time.parse()) và mặc dù tôi gửi thời gian UTC, 'này tắt bởi một giờ 'DST vấn đề cây trồng rất nhiều. Ngay cả khi sử dụng '.gmtime()' không phải lúc nào cũng sửa chữa nó.
Rõ ràng sự khác biệt được gây ra bằng cách nào đó bởi một chuyển đổi tiềm ẩn ở đâu đó dẫn đến BST được xử lý không chính xác như UTC, nhưng tại sao? Không đường ray lưu trữ dấu thời gian trong UTC? Không phải là múi giờ của Lớp thời gian nhận thức? Tôi đang sử dụng Rails 2.2.2
Vậy điều gì đang xảy ra ở đây - và cách an toàn để lập trình xung quanh nó là gì?
chỉnh sửa, một số thông tin bổ sung để hiển thị những gì DB và lớp Thời gian đang làm:
>> Model.find(:last).created_at
=> Tue, 11 Aug 2009 20:31:07 UTC +00:00
>> Time.now
=> Tue Aug 11 22:00:18 +0100 2009
>> Time.now.gmtime
=> Tue Aug 11 21:00:22 UTC 2009
Thú vị ... là Time.utc một từ đồng nghĩa với Time.gmtime? Tôi cũng nhận được >> Time.zone => #>. Tôi nghĩ rằng vấn đề là theo cách suy nghĩ của tôi "Thứ Ba ngày 11 tháng 8 22:00:18 +0100 2009" và "Thứ Ba ngày 11 tháng 8 21:00:22 UTC 2009" tham khảo cùng một thời gian hợp lý. Tôi đoán rằng đường ray/ruby chỉ đơn giản là bỏ qua sự bù đắp khi xây dựng SQL. –
frankodwyer
Tôi tin rằng Time # utc chỉ là bí danh đối với Time # gmtime.Ngoài ra, bù trừ múi giờ được bỏ qua khi giao dịch với thời gian bình thường (Time.now) nhưng được tính đến khi sử dụng Time.zone.now. Vì vậy, tốt nhất để luôn luôn sử dụng Time.zone sau đó bạn không cần phải gọi "utc" trên đó. – ryanb
cảm ơn, điều đó giúp ích rất nhiều. nó không rõ ràng với tôi rằng nó hoạt động theo cách đó nhưng ít nhất tôi hiểu những gì đang xảy ra bây giờ. Tôi đã thay đổi mã cho phù hợp và có vẻ như đã xóa vấn đề. Một điều mà đã ném mã của tôi là 1. năm không chia hết cho 1.weeks như tôi mong đợi nó được ... Tôi đã làm một vòng lặp và nhận được một lỗi không liên quan nhưng tương tự vì điều đó. – frankodwyer