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

Xử lý đúng TIME WITH TIME ZONE trong PostgreSQL

Bạn đã khẳng định rằng:

Vì vậy, bạn không bao giờ vượt qua đường dữ liệu trong cùng một hàng. Tôi khuyên bạn nên lưu 1x date 3x time múi giờ (dưới dạng text hoặc cột FK):

CREATE TABLE legacy_table (
   event_id      bigint PRIMARY KEY NOT NULL
 , report_date   date NOT NULL
 , start_hour    time
 , end_hour      time
 , expected_hour time
 , tz            text  -- time zone
);

Giống như bạn đã tìm thấy, timetz (time with time zone ) thường nên tránh . Nó không thể xử lý đúng các quy tắc DST ( d aylight s aving t ime).

Vì vậy, về cơ bản những gì bạn đã có . Chỉ cần bỏ thành phần ngày tháng khỏi start_hour , đó là cước phí chết. Truyền timestamp đến time để cắt bỏ ngày tháng. Như:(timestamp '2018-03-25 1:00:00')::time

tz có thể là bất kỳ chuỗi nào được chấp nhận bởi AT TIME ZONE nhưng để xử lý các múi giờ khác nhau một cách đáng tin cậy, tốt nhất bạn nên sử dụng riêng tên múi giờ. Bất kỳ name nào bạn tìm thấy trong danh mục hệ thống pg_timezone_names .

Để tối ưu hóa dung lượng, bạn có thể thu thập các tên múi giờ được phép trong một bảng tra cứu nhỏ và thay thế bằng tz text với tz_id int REFERENCES my_tz_table .

Hai hàng mẫu có và không có DST:

INSERT INTO legacy_table VALUES
   (1, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Vienna')  -- sadly, with DST
 , (2, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Moscow'); -- Russians got rid of DST

Đối với mục đích biểu diễn hoặc tính toán, bạn có thể làm những việc như:

SELECT (report_date + start_hour)    AT TIME ZONE tz AT TIME ZONE 'UTC' AS start_utc
     , (report_date + end_hour)      AT TIME ZONE tz AT TIME ZONE 'UTC' AS end_utc
     , (report_date + expected_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS expected_utc
     -- START_HOUR - END_HOUR
     , (report_date + start_hour) AT TIME ZONE tz
     - (report_date + end_hour)   AT TIME ZONE tz AS start_minus_end
FROM   legacy_table;

Bạn có thể tạo một hoặc nhiều chế độ xem để dễ dàng hiển thị các chuỗi khi cần thiết. Bảng dùng để lưu trữ thông tin bạn cần .

Lưu ý dấu ngoặc đơn! Khác toán tử + sẽ ràng buộc trước AT TIME ZONE do ưu tiên toán tử .

Và hãy xem kết quả:

db <> fiddle tại đây

Vì thời gian được điều chỉnh ở Vienna (giống như bất kỳ nơi nào áp dụng các quy tắc DST ngớ ngẩn), bạn sẽ nhận được kết quả "đáng ngạc nhiên".

Có liên quan:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Entity Framework Core - cách hiệu quả để cập nhật Entity có con dựa trên biểu diễn JSON của thực thể được chuyển vào qua Web API

  2. Tìm ra số tháng giữa 2 ngày

  3. pgFincore 1.2, một phần mở rộng PostgreSQL

  4. Cấu hình cơ sở dữ liệu ActiveRecord ::AdapterNotSpecified không chỉ định bộ điều hợp

  5. Dữ liệu C # hàng loạt vào bảng postgresql