Anda menegaskan bahwa:
Jadi Anda tidak pernah melewati garis tanggal dalam baris yang sama. Saya sarankan untuk menyimpan 1x date
3x time
dan zona waktu (sebagai text
atau kolom FK):
CREATE TABLE legacy_table (
event_id bigint PRIMARY KEY NOT NULL
, report_date date NOT NULL
, start_hour time
, end_hour time
, expected_hour time
, tz text -- time zone
);
Seperti yang sudah Anda temukan, timetz
(time with time zone
) umumnya harus dihindari
. Itu tidak dapat menangani aturan DST dengan benar (d aylight s menghindari t waktu).
Jadi pada dasarnya apa yang sudah Anda miliki . Cukup jatuhkan komponen tanggal dari start_hour
, itu barang mati. Keluarkan timestamp
ke time
untuk memotong tanggal. Suka:(timestamp '2018-03-25 1:00:00')::time
tz
dapat berupa string apa pun yang diterima oleh AT TIME ZONE
membangun, tetapi untuk menangani zona waktu yang berbeda dengan andal, yang terbaik adalah menggunakan nama zona waktu secara eksklusif. name
Any Anda temukan di katalog sistem pg_timezone_names
.
Untuk mengoptimalkan penyimpanan, Anda dapat mengumpulkan nama zona waktu yang diizinkan dalam tabel pencarian kecil dan mengganti tz text
dengan tz_id int REFERENCES my_tz_table
.
Dua contoh baris dengan dan tanpa DST:
INSERT INTO legacy_table VALUES
(1, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Vienna') -- sadly, with DST
, (2, '2018-03-25', '1:00', '3:00', '2:00', 'Europe/Moscow'); -- Russians got rid of DST
Untuk tujuan representasi atau perhitungan, Anda dapat melakukan hal-hal seperti:
SELECT (report_date + start_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS start_utc
, (report_date + end_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS end_utc
, (report_date + expected_hour) AT TIME ZONE tz AT TIME ZONE 'UTC' AS expected_utc
-- START_HOUR - END_HOUR
, (report_date + start_hour) AT TIME ZONE tz
- (report_date + end_hour) AT TIME ZONE tz AS start_minus_end
FROM legacy_table;
Anda dapat membuat satu atau beberapa tampilan untuk dengan mudah menampilkan string sesuai kebutuhan. Tabel ini untuk menyimpan informasi yang Anda butuhkan .
Perhatikan tanda kurung! Jika tidak, operator +
akan mengikat sebelum AT TIME ZONE
karena pengutamaan operator
.
Dan lihatlah hasilnya:
db<>fiddle di sini
Karena waktu dimanipulasi di Wina (seperti tempat di mana aturan DST konyol berlaku), Anda mendapatkan hasil yang "mengejutkan".
Terkait:
- Menghitung DST di Postgres, saat memilih item terjadwal
- Mengabaikan waktu zona sama sekali di Rails dan PostgreSQL