sql >> データベース >  >> RDS >> PostgreSQL

KnexはPostgresのタイムスタンプをタイムゾーンでサイレントに変換し、誤った時間を返します

    特定のタイムゾーンのデータベースから日時をクエリし、タイムスタンプのタイプをタイムゾーンのないタイムスタンプに効果的に変換しているため、おそらく問題が発生しています。その場合、データベースは、時間を返したタイムゾーンがどのタイムゾーンであったかに関する情報をknexに送信しません。

    したがって、knex(またはknexが使用しているpgドライバー)は、タイムスタンプを現地時間として解釈します。これは、knexを実行しているアプリケーションサーバーのタイムゾーン設定によって異なります。

    UTCと同じように時間をフェッチし、モーメントまたはルクソンライブラリを使用してJavaScript側でタイムゾーン変換を行うことができます(タイムゾーンの処理には後者のIMOの方が適しています)。

    他の解決策は、タイムスタンプとタイムゾーンタイプのタイムスタンプをJavaScriptに変換しないようにpgドライバーに指示することです。 Date オブジェクト。

    これは次のように実行できます( https://github.com/brianc/node-pg-タイプ ):

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

    すべてのタイムスタンプを文字列として返すようにするこのコードは、たとえばknexfile.jsの先頭に追加できます。 。これらの返される文字列は、データベースサーバー自体によって返されるものとまったく同じ形式になります。

    編集:

    元の投稿のコードで、タイムスタンプがタイムゾーンUTCに変換されるとき データベースサーバーは、timestamp with time zoneを変換します 通常のtimestamp without time zoneに入力します そのため、戻り値にはタイムゾーン情報がありません。タイムゾーン情報を追加し直すには、たとえば、次のように、返されたタイムスタンプの末尾に+02を追加します。

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

    2010-01-01 00:00:00+00を返します pgドライバーでも正しく読み取れるドライバーに。

    これにより、SET TIME ZONE 'UTC';を設定するのと同じことが効果的に行われます。 接続が作成され、timestamptz列を直接返すときにdbサーバーで:

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

    2009-12-31 22:00:00+00を返します 。




    1. どこでも奇妙

    2. 19.3PDBクローズORA-65107ORA-16078

    3. MacでMySqlを使用する方法

    4. PostgreSQLで静的Qt5.10.0をコンパイル中にエラーが発生しました