Như bạn đã tự tìm hiểu, múi giờ hoàn toàn không được lưu với các loại ngày / giờ Postgres, thậm chí không được lưu với timestamptz
. Vai trò của nó chỉ là một công cụ sửa đổi đầu vào hoặc một trình trang trí đầu ra, tương ứng. Chỉ giá trị (thời điểm) được lưu. Chi tiết đầy đủ trong câu trả lời liên quan này:
- Bỏ qua hoàn toàn các múi giờ trong Rails và PostgreSQL
Do đó, nếu bạn muốn bảo toàn phần đó của chuỗi đầu vào, bạn phải giải nén nó ra khỏi chuỗi và tự lưu nó. Tôi sẽ sử dụng một bảng như sau:
CREATE TABLE tstz
...
, ts timestamp -- without time zone
, tz text
)
tz
, là text
, có thể giữ một số offset cũng như một chữ viết tắt của múi giờ hoặc múi giờ tên .
Khó khăn là trích xuất phần múi giờ theo tất cả các quy tắc khác nhau mà trình phân tích cú pháp tuân theo và theo cách không dễ dàng bị phá vỡ. Thay vì soạn thảo quy trình của riêng bạn, hãy yêu cầu trình phân tích cú pháp thực hiện công việc . Hãy xem xét bản trình diễn này:
WITH ts_literals (tstz) AS (
VALUES ('2013-11-28 23:09:11.761166+03'::text)
,('2013-11-28 23:09:11.761166 CET')
,('2013-11-28 23:09:11.761166 America/New_York')
)
SELECT tstz
,tstz::timestamp AS ts
,right(tstz, -1 * length(tstz::timestamp::text)) AS tz
FROM ts_literals;
SQL Fiddle.
Hoạt động có hoặc không có T
giữa ngày và giờ. Logic chính là ở đây:
right(tstz, -1 * length(tstz::timestamp::text)) AS tz
Lấy phần còn lại của chuỗi dấu thời gian sau khi cắt bớt độ dài của phần mà trình phân tích cú pháp đã xác định là thành phần ngày / giờ. Điều này phụ thuộc vào dữ liệu đầu vào, như bạn đã nêu:
các chuỗi ISO8601 đã được xác thực