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

Knex secara diam-diam mengubah cap waktu Postgres dengan zona waktu dan mengembalikan waktu yang salah

Mungkin ada yang gagal karena ketika Anda menanyakan waktu dari basis data di zona waktu tertentu dan secara efektif mengubah jenis stempel waktu menjadi stempel waktu tanpa zona waktu. Dalam hal ini database tidak akan mengirimkan informasi ke knex tentang zona waktu mana yang mengembalikan waktu itu.

Jadi knex (atau lebih tepatnya driver pg yang digunakan knex) menafsirkan stempel waktu Anda sebagai waktu lokal, yang bergantung pada pengaturan zona waktu server aplikasi Anda yang menjalankan knex.

Anda dapat mengambil waktu seperti UTC dan melakukan konversi zona waktu di sisi JavaScript dengan pustaka momen atau luxon (IMO terakhir lebih baik untuk penanganan zona waktu).

Solusi lain adalah memberi tahu driver pg bahwa stempel waktu dan stempel waktu dengan tipe zona waktu tidak boleh dikonversi ke JavaScript Date objek.

Itu dapat dilakukan seperti ini (https://github.com/brianc/node-pg- jenis ):

const types = require('pg').types;
const TIMESTAMPTZ_OID = 1184;
const TIMESTAMP_OID = 1114;
types.setTypeParser(TIMESTAMPTZ_OID, val => val);
types.setTypeParser(TIMESTAMP_OID, val => val);

Kode ini yang membuat semua cap waktu dikembalikan sebagai string yang dapat ditambahkan misalnya di awal knexfile.js . String yang dikembalikan tersebut akan persis dalam format yang sama dengan yang dikembalikan oleh server database itu sendiri.

EDIT:

Dalam kode di pos asli, ketika stempel waktu diubah menjadi zona waktu UTC server database mengonversi timestamp with time zone ketik menjadi normal timestamp without time zone jadi nilai yang dikembalikan tidak memiliki informasi zona waktu. Untuk menambahkan kembali informasi zona waktu, misalnya, Anda dapat menambahkan +02 di akhir stempel waktu yang dikembalikan seperti ini:

select ('2010-01-01T00:00:00.000Z'::timestamptz AT TIME ZONE 'UTC')::text || '+00';

Yang mengembalikan 2010-01-01 00:00:00+00 ke driver yang dapat dibaca dengan benar oleh driver pg juga.

Ini akan secara efektif melakukan hal yang sama yang hanya mengatur SET TIME ZONE 'UTC'; di server db saat koneksi dibuat dan baru saja mengembalikan kolom timestamptz secara langsung:

SET TIME ZONE 'UTC';
select '2010-01-01T00:00:00.000+02:00'::timestamptz;

Yang akan mengembalikan 2009-12-31 22:00:00+00 .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pilih Query untuk memeriksa keduanya atau salah satu atau kondisi

  2. Bagaimana cara mengabaikan tanda tanya sebagai pengganti saat menggunakan PDO dengan PostgreSQL

  3. cara membuka koneksi PostgreSQL dari IBM WSJdbc41Connection

  4. Mengapa postgresql tidak menggunakan indeks dalam kueri ini?

  5. Otentikasi kata sandi Postgres gagal