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
.