Seperti yang sudah Anda ketahui sendiri, zona waktu tidak disimpan sama sekali dengan tipe tanggal/waktu Postgres, bahkan dengan timestamptz
. Perannya hanya sebagai pengubah input atau dekorator output, masing-masing. Hanya nilai (titik waktu) yang disimpan. Banyak detail dalam jawaban terkait ini:
- Mengabaikan zona waktu sama sekali di Rails dan PostgreSQL
Oleh karena itu, jika Anda ingin mempertahankan bagian dari string input tersebut, Anda harus mengekstraknya dari string dan menyimpannya sendiri. Saya akan menggunakan tabel seperti:
CREATE TABLE tstz
...
, ts timestamp -- without time zone
, tz text
)
tz
, menjadi text
, dapat menampung offset numer numerik serta singkatan zona waktu , atau nama zona waktu .
Kesulitannya adalah mengekstrak bagian zona waktu sesuai dengan semua berbagai aturan yang diikuti parser dan dengan cara yang tidak mudah rusak. Alih-alih memasak prosedur Anda sendiri, buat parser yang bekerja . Pertimbangkan demo ini:
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.
Bekerja dengan atau tanpa T
antara tanggal dan waktu. Logika kuncinya ada di sini:
right(tstz, -1 * length(tstz::timestamp::text)) AS tz
Ambil apa yang tersisa dari string stempel waktu setelah memangkas panjang dari apa yang diidentifikasi oleh parser sebagai komponen tanggal/waktu. Ini bergantung pada input, seperti yang Anda nyatakan:
string ISO8601 yang divalidasi