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

Thể hiện thời gian trong tương lai trong PostgreSQL

Có vẻ như bạn muốn lưu trữ một localtime đối với một múi giờ nhất định. Trong trường hợp đó, hãy lưu trữ timestamp (không có múi giờ) và timezone trong một cột riêng biệt.

Ví dụ:giả sử bạn muốn ghi lại một sự kiện sẽ xảy ra lúc 10 giờ sáng ngày 26 tháng 2 năm 2030 ở Chicago và nó phải là 10 giờ sáng giờ địa phương bất kể quy tắc múi giờ có hiệu lực vào ngày đó.

Nếu cơ sở dữ liệu lưu trữ dấu thời gian không có múi giờ:

unutbu=# select '2030-02-26 10:00:00'::timestamp as localtime, 'America/Chicago' AS tzone;
+---------------------+-----------------+
|      localtime      |      tzone      |
+---------------------+-----------------+
| 2030-02-26 10:00:00 | America/Chicago |
+---------------------+-----------------+

Sau đó, bạn có thể tìm ngày giờ UTC của sự kiện bằng cách sử dụng

unutbu=# select '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2030-02-26 16:00:00 |
+---------------------+

Truy vấn trả về ngày giờ UTC, 2030-02-26 16:00:00 , tương ứng với 2030-02-26 10:00:00 giờ địa phương ở Chicago.

Sử dụng AT TIME ZONE trì hoãn việc áp dụng các quy tắc múi giờ khi truy vấn được thực hiện thay vì khi timestamptz đã được chèn.

Sử dụng AT TIME ZONE trên timestamp bản địa hóa ngày giờ thành múi giờ nhất định, nhưng báo cáo ngày giờ trong múi giờ của người dùng .Sử dụng AT TIME ZONE trên timestamptz chuyển đổi ngày giờ thành múi giờ nhất định, sau đó giảm độ lệch, do đó trả về timestamp .Above, AT TIME ZONE được sử dụng hai lần:lần đầu tiên để bản địa hóa timestamp và tiếp theo để chuyển đổi timestamptz được trả về sang múi giờ mới (UTC). Kết quả là một timestamp theo giờ UTC.

Đây là một ví dụ minh họa AT TIME ZONE hành vi của timestamp s:

unutbu=# SET timezone = 'America/Chicago';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
|        timezone        |
+------------------------+
| 2030-02-26 10:00:00-06 |
+------------------------+

unutbu=# SET timezone = 'America/Los_Angeles';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
|        timezone        |
+------------------------+
| 2030-02-26 08:00:00-08 |
+------------------------+

2030-02-26 10:00:00-062030-02-26 08:00:00-08 là cùng ngày giờ nhưng được báo cáo theo múi giờ của người dùng khác nhau. Điều này cho thấy 10 giờ sáng ở Chicago là 8 giờ sáng ở Los Angeles (sử dụng định nghĩa múi giờ hiện tại):

unutbu=# SELECT '2030-02-26 10:00:00-06'::timestamptz AT TIME ZONE 'America/Los_Angeles';
+---------------------+
|      timezone       |
+---------------------+
| 2030-02-26 08:00:00 |
+---------------------+

Một giải pháp thay thế cho việc sử dụng AT TIME ZONE hai lần là đặt múi giờ của người dùng sang UTC . Sau đó, bạn có thể sử dụng

select localtime AT TIME ZONE tzone

Lưu ý rằng khi thực hiện theo cách này, timestamptz được trả lại thay vì timestamp .

Lưu ý rằng việc lưu trữ thời gian cục bộ có thể có vấn đề vì có thể có thời gian không tồn tại và thời gian không rõ ràng. Ví dụ:2018-03-11 02:30:00 là giờ địa phương không tồn tại ở America/Chicago . Postgresql chuẩn hóa thời gian cục bộ không tồn tại bằng cách giả sử nó đề cập đến thời gian tương ứng sau khi Giờ tiết kiệm ánh sáng ban ngày (DST) bắt đầu (như thể ai đó quên đặt đồng hồ của họ về phía trước):

unutbu=# select '2018-03-11 02:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)

unutbu=# select '2018-03-11 03:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)

Ví dụ về localtime không rõ ràng là 2018-11-04 01:00:00America/Chicago . Nó xảy ra hai lần do DST. Postgresql giải quyết sự không rõ ràng này bằng cách chọn thời gian muộn hơn, sau khi DST kết thúc:

unutbu=# select '2018-11-04 01:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-11-04 07:00:00 |
+---------------------+

Lưu ý rằng điều này có nghĩa là không có cách nào để tham chiếu đến 2018-11-04 06:00:00 UTC bằng cách lưu trữ giờ địa phương ở America/Chicago múi giờ:

unutbu=# select '2018-11-04 00:59:59'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-11-04 05:59:59 |
+---------------------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ràng buộc khóa ngoại phức tạp trong SQLAlchemy

  2. NodeJS / Knex Tạo phản hồi Json

  3. Django mô hình một khóa ngoại cho nhiều bảng

  4. Làm cách nào để nhập mô-đun hoặc cài đặt tiện ích mở rộng trong Postgres?

  5. Phân tích / lập hồ sơ truy vấn trên PostgreSQL