web-dev-qa-db-ja.com

PostgresQLの日付/時刻フィールドが秒数からの範囲外です

CsvファイルをPostgreSQLデータベースにインポートしています。ほとんどのファイルは、このメッセージが表示されるまで問題なくインポートされます

ERROR:  date/time field value out of range: "1421088300"
HINT:  Perhaps you need a different "datestyle" setting.
CONTEXT:  COPY accidents, line 6356158, column datetime: "1421088300"

しかし、これは https://www.unixtimestamp.com/index.php によれば、01/12/2015 @ 6:45 pm(UTC)の有効なタイムスタンプのようです

では、なぜ範囲外なのでしょうか?

4
falcs

エポックのタイムスタンプからの秒数

「タイムスタンプ」は、エポック以降の秒数です。 dezsoごとに、to_timestamp()を使用します。 \dfS+

悪い複雑な考え、そしてドラゴン。

チェック 入力フォーマット 。弦のキャストをカバーします。これがCOPYが内部で行っていることです。リモートでも長い数字のように見える唯一の方法はISO 8601です。この例を見ると、秒ではないことがわかります。

Example    | Description
19990108   | ISO 8601; January 8, 1999 in any mode

これは基本的に、そのチャートの別の例と同じです。

Example    | Description
1999-01-08 | ISO 8601; January 8, 1999 in any mode

timestampを中間形式としてabstimeに変換する

したがって、seconds-since-Epochから変換する場合は、seconds-since-Epochの文字列からタイムスタンプに直接キャストできるキャストがないため、内部abstimeを使用してチートできます。

SELECT 1421088300::abstime::timestamp;
      timestamp      
---------------------
 2015-01-12 12:45:00
(1 row)

ここで起こっているのは、abstimeintegerと強制的にバイナリ変換できることです。 \dC+。私はチェックした \dfS+関数が整数からタイムスタンプに取得し、何も見つからなかった場合。ただし、整数からabstime(整数として格納されます)へのキャストと、abstimeからtimestampへのキャストがあります。

これが新しいテーブルである場合、実際にはその列をabstimeと入力できます。完全に正常に読み込まれるはずです。そして、あなたはALTER TABLE。以下は例ですが、COPYを実行していません(ただし、すべて同じように機能するはずです)。

CREATE TABLE foo(bar)
AS VALUES
  (1421088300::abstime);

TABLE foo;
          bar           
------------------------
 2015-01-12 12:45:00-06
(1 row)

ALTER TABLE foo
  ALTER bar
  TYPE timestamp;

TABLE foo;
         bar         
---------------------
 2015-01-12 12:45:00
(1 row)

\d foo;
                Table "public.foo"
 Column |            Type             | Modifiers 
--------+-----------------------------+-----------
 bar    | timestamp without time zone | 
4
Evan Carroll