Trong postgres, timestamp with time zone
có thể được viết tắt là timestamptz
, và timestamp without time zone
như timestamp
. Tôi sẽ sử dụng tên loại ngắn hơn để đơn giản.
Lấy dấu thời gian Unix từ một postgres timestamptz
như now()
đơn giản, như bạn nói, chỉ cần:
select extract(epoch from now());
Đó thực sự là tất cả những gì bạn cần biết về việc có được thời gian tuyệt đối từ bất cứ thứ gì thuộc loại timestamptz
, kể cả now()
.
Mọi thứ chỉ trở nên phức tạp khi bạn có một timestamp
lĩnh vực.
Khi bạn đặt timestamptz
dữ liệu như now()
vào trường đó, trước tiên nó sẽ được chuyển đổi thành múi giờ cụ thể (rõ ràng bằng at time zone
hoặc chuyển đổi sang múi giờ phiên) và thông tin múi giờ bị loại bỏ . Nó không còn đề cập đến một thời gian tuyệt đối. Đây là lý do tại sao bạn thường không muốn lưu trữ dấu thời gian như timestamp
thường sử dụng timestamptz
- có thể một bộ phim được phát hành vào lúc 6 giờ tối vào một ngày cụ thể trong mỗi múi giờ , đó là loại trường hợp sử dụng.
Nếu bạn chỉ làm việc trong một múi giờ duy nhất, bạn có thể thoát khỏi (mis) bằng cách sử dụng timestamp
. Chuyển đổi trở lại timestamptz
đủ thông minh để đối phó với DST và dấu thời gian được giả định, cho mục đích chuyển đổi, nằm trong múi giờ hiện tại. Đây là một ví dụ cho GMT / BST:
select '2011-03-27 00:59:00.0+00'::timestamptz::timestamp::timestamptz
, '2011-03-27 01:00:00.0+00'::timestamptz::timestamp::timestamptz;
/*
|timestamptz |timestamptz |
|:---------------------|:---------------------|
|2011-03-27 00:59:00+00|2011-03-27 02:00:00+01|
*/
DBFiddle
Nhưng, lưu ý hành vi khó hiểu sau đây:
set timezone to 0;
values(1, '1970-01-01 00:00:00+00'::timestamp::timestamptz)
, (2, '1970-01-01 00:00:00+02'::timestamp::timestamptz);
/*
|column1|column2 |
|------:|:---------------------|
| 1|1970-01-01 00:00:00+00|
| 2|1970-01-01 00:00:00+00|
*/
DBFiddle
Điều này là do :
PostgreQuery không bao giờ kiểm tra nội dung của một chuỗi ký tự trước khi xác định loại của nó và do đó sẽ coi cả [[]] là dấu thời gian không có múi giờ. Để đảm bảo rằng một chữ được coi là dấu thời gian với múi giờ, hãy đặt cho nó một kiểu rõ ràng chính xác Trong một chữ được xác định là dấu thời gian không có múi giờ, PostgreQuery sẽ âm thầm bỏ qua bất kỳ dấu hiệu múi giờ nào