PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Knex po cichu konwertuje znaczniki czasu Postgres ze strefą czasową i zwraca niepoprawny czas

Prawdopodobnie coś się nie udaje, ponieważ podczas sprawdzania daty i godziny z bazy danych w określonej strefie czasowej i efektywnej konwersji typu znacznika czasu na znacznik czasu bez strefy czasowej. W takim przypadku baza danych nie wyśle ​​do Knex informacji o strefie czasowej, w której znajdował się czas.

Tak więc knex (a raczej sterownik pg, którego używa knex) interpretuje twój znacznik czasu jako czas lokalny, który zależy od ustawień strefy czasowej twojego serwera aplikacji z uruchomionym knexem.

Możesz pobierać czas tak samo jak UTC i przeprowadzać konwersję stref czasowych po stronie JavaScript za pomocą bibliotek moment lub luxon (ostatnia IMO jest lepsza do obsługi stref czasowych).

Innym rozwiązaniem byłoby poinformowanie sterownika pg, że znacznik czasu i znacznik czasu z typami stref czasowych nie powinny być konwertowane na JavaScript Date przedmioty.

Można to zrobić w ten sposób (https://github.com/brianc/node-pg- typy ):

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);

Ten kod, który sprawia, że ​​wszystkie znaczniki czasu mają być zwracane jako ciągi znaków, można dodać na przykład na początku knexfile.js . Te zwrócone łańcuchy będą dokładnie w tym samym formacie, w jakim zostały zwrócone przez sam serwer bazy danych.

EDYCJA:

W kodzie w oryginalnym poście, gdy znacznik czasu jest konwertowany na strefę czasową UTC serwer bazy danych konwertuje timestamp with time zone wpisz, aby być normalnym timestamp without time zone więc zwracana wartość nie zawiera informacji o strefie czasowej. Aby dodać informacje o strefie czasowej z powrotem, możesz na przykład dodać +02 na końcu zwróconego znacznika czasu w następujący sposób:

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

Co zwraca 2010-01-01 00:00:00+00 do sterownika, który może być poprawnie odczytany również przez sterownik pg.

To skutecznie zrobi to samo, co ustawienie SET TIME ZONE 'UTC'; w serwerze db, gdy połączenie jest tworzone i po prostu zwraca bezpośrednio kolumnę timestamptz:

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

Który zwróci 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. Znajdź nakładające się zakresy dat w PostgreSQL

  2. Zalety korzystania z URLField zamiast TextField?

  3. PostgreSQL generate_series() z funkcją SQL jako argumentami

  4. Zwróć identyfikator, jeśli wiersz istnieje, WSTAW W przeciwnym razie

  5. PostgreSQL:VACUM FULL vs pg_dump i przywracanie