PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Tangani WAKTU DENGAN ZONA WAKTU dengan benar di PostgreSQL

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:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menghindari kondisi balapan saat menggunakan metode find_or_create dari DBIx::Class::ResultSet?

  2. Beberapa Basis Data Dengan Rel Tidak Berfungsi Untuk Basis Data Jarak Jauh

  3. Bagaimana cara melakukan transaksi database dengan psycopg2/python db api?

  4. Optimalkan rentang kueri cap waktu Postgres

  5. Mengapa aturan ini tidak mencegah pelanggaran kunci duplikat?