PostgresSQL 日期/时间字段在自纪元以来的秒数范围内超出范围

fal*_*lcs 6 postgresql timestamp datetime postgresql-9.5

我正在将 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"
Run Code Online (Sandbox Code Playgroud)

但这似乎是 01/12/2015 @ 6:45pm (UTC) 根据https://www.unixtimestamp.com/index.php的有效时间戳

那么为什么会超出范围呢?

Eva*_*oll 6

自纪元时间戳以来的秒数

您的“时间戳”以自纪元以​​来的秒为单位。根据 dezso,使用to_timestamp(). 当我检查时我错过了\dfS+

糟糕的复杂想法,还有龙。

检查输入格式。它们涵盖了字符串的演员表。这COPY就是幕后所做的事情。唯一看起来像一个长数字的唯一方法是 ISO 8601。如果你看那个例子,虽然你会发现它不是自纪元以来的秒数

Example    | Description
19990108   | ISO 8601; January 8, 1999 in any mode
Run Code Online (Sandbox Code Playgroud)

这与该图表上的另一个示例基本相同。

Example    | Description
1999-01-08 | ISO 8601; January 8, 1999 in any mode
Run Code Online (Sandbox Code Playgroud)

转换为timestampwithabstime作为中间格式

因此,如果您想从自纪元以来的秒数转换,您可以使用内部作弊,abstime因为没有可用的直接从一串自纪元以来的秒数转换为时间戳的可用方法。

SELECT 1421088300::abstime::timestamp;
      timestamp      
---------------------
 2015-01-12 12:45:00
(1 row)
Run Code Online (Sandbox Code Playgroud)

这里发生的事情是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 | 
Run Code Online (Sandbox Code Playgroud)