Về cơ bản những gì bạn muốn là:
$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40
Tôi nhận được giải pháp từ bài viết này là bên dưới, đó là VÀNG thẳng !!! Nó giải thích vấn đề không nhỏ này rất rõ ràng, hãy đọc nó nếu bạn muốn hiểu rõ hơn về quản lý pstgrsql TZ.
Biểu thị dấu thời gian PostgreSQL không có múi giờ theo giờ địa phương
Đây là những gì đang xảy ra. Trước tiên, bạn nên biết rằng 'múi giờ PST chậm hơn 8 giờ so với múi giờ UTC, ví dụ:ngày 1 tháng 1 năm 2014, 4:30 chiều theo giờ PST (Thứ tư, ngày 1 tháng 1 năm 2014 16:00:30 -0800) tương đương với ngày 2 tháng 1 năm 2014, 00:30 AM UTC (Thứ 2, ngày 2 tháng 1 năm 2014, 00:00:30 +0000). Bất kỳ lúc nào sau 4:00 chiều theo giờ PST đều chuyển sang ngày tiếp theo, được hiểu là UTC.
Ngoài ra, như Erwin Brandstetter đã đề cập ở trên, postresql có hai loại dữ liệu dấu thời gian, một loại có múi giờ và một loại không có. Nếu dấu thời gian của bạn bao gồm múi giờ, thì đơn giản là:
$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40
sẽ làm việc. Tuy nhiên, nếu dấu thời gian của bạn không có múi giờ, việc thực hiện lệnh trên sẽ không hoạt động và trước hết bạn phải chuyển đổi dấu thời gian không có múi giờ của mình thành dấu thời gian có múi giờ, cụ thể là múi giờ UTC và CHỈ SAU ĐÓ chuyển đổi nó thành 'PST' hoặc 'US / mong muốn của bạn Thái Bình Dương '(đều giống nhau ở một số vấn đề về thời gian tiết kiệm ánh sáng ban ngày. Tôi nghĩ bạn sẽ ổn).
Hãy để tôi chứng minh bằng một ví dụ trong đó tôi tạo dấu thời gian không có múi giờ. Để thuận tiện, hãy giả sử rằng múi giờ địa phương của chúng ta thực sự là 'PST' (nếu không phải thì nó phức tạp hơn một chút, điều này không cần thiết cho mục đích của lời giải thích này).
Giả sử tôi có:
$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d
Điều này sẽ mang lại:
"a"=>"2014-01-02 00:30:00" (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"
Dấu thời gian cuối cùng là lý do cho tất cả sự nhầm lẫn liên quan đến việc chuyển đổi dấu thời gian không có múi giờ từ UTC sang 'PST' trong postgresql. Khi chúng tôi viết:
timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d
Chúng tôi đang sử dụng dấu thời gian không có múi giờ và cố gắng chuyển đổi nó thành 'PST TZ (chúng tôi gián tiếp giả định rằng postgresql sẽ hiểu rằng chúng tôi muốn nó chuyển đổi dấu thời gian từ UTC TZ, nhưng postresql có kế hoạch của riêng nó!). Trong thực tế, những gì postgresql làm là nó lấy dấu thời gian không có múi giờ ('2014-01-2 00:30:00) và coi nó như thể nó ĐÃ CÓ dấu thời gian' PST 'TZ (tức là:2014-01-2 00:30 :00 -0800) và chuyển đổi sang múi giờ UTC !!! Vì vậy, nó thực sự đẩy nó đi trước 8 giờ thay vì lùi lại! Do đó, chúng tôi nhận được (2014-01-02 08:30:00 + 00).
Dù sao, hành vi cuối cùng (không trực quan) này là nguyên nhân của mọi sự nhầm lẫn. Hãy đọc bài viết nếu bạn muốn được giải thích cặn kẽ hơn, tôi thực sự nhận được kết quả hơi khác một chút so với kết quả ở phần cuối cùng này, nhưng ý tưởng chung là giống nhau.