PostgreSQL支持最早的时间戳

dou*_*yte 11 sql postgresql timestamp date

我在许多不同的时区(和时间段)使用不同的数据库,并且通常产生问题的一件事是日期/时间定义.

出于这个原因,并且由于日期是对起始值的引用,为了跟踪它的计算方式,我尝试存储基准日期; 即:该特定计算机/数据库支持的最短日期;

如果我看得很清楚,这取决于RDBMS和类型的特定存储.在SQL Server中,我发现了几种计算这个"基准日期"的方法;

SELECT CONVERT(DATETIME, 0) 
Run Code Online (Sandbox Code Playgroud)

要么

SELECT DATEADD(MONTH, 0, 0 ) 
Run Code Online (Sandbox Code Playgroud)

甚至像这样的演员:

DECLARE @300 BINARY(8) 
SET @300 = 0x00000000 + CAST(300 AS BINARY(4))
set @dt=(SELECT CAST(@300 AS DATETIME) AS BASEDATE)
print CAST(@dt AS NVARCHAR(100))
Run Code Online (Sandbox Code Playgroud)

(其中@dt是日期时间变量)

我的问题是,是否有类似的方法来计算PostgreSQL中的基准日期,即:支持的最小日期值是否在所有计算的基础上?

date类型的描述,我可以看到支持的最小日期是公元前4713年,但有没有办法以编程方式获取此值(例如作为格式化的日期字符串),就像我在SQL Server中一样?

Cra*_*ger 10

手册将值表示为:

  • 低值:公元前4713年
  • 物超所值:公元294276

正如克里斯所说,随着警告,这-infinity也得到了支持.

请参阅本手册同一页后面的说明 ; 如果您使用的是整数时间戳,则上述情况才适用,这是所有模糊的PostgreSQL版本中的默认值.如果有疑虑:

SHOW integer_datetimes;
Run Code Online (Sandbox Code Playgroud)

会告诉你的.如果您正在使用浮点日期时间,则会获得更大的范围和更小(非线性)的精度.任何以编程方式计算出最小值的尝试都必须应对这种限制.

PostgreSQL不只是让你将零转换为时间戳以获得最小可能的时间戳,如果你使用浮点日期时间,这也没有多大意义.您可以使用Julian日期转换功能,但是这给你的时代不是最小时间:

postgres=> select to_timestamp(0);
      to_timestamp      
------------------------
 1970-01-01 08:00:00+08
(1 row)
Run Code Online (Sandbox Code Playgroud)

因为它接受负值.你认为给它负maxint会起作用,但结果令人惊讶,我想知道我们是否有潜伏在这里的环绕错误:

postgres=> select to_timestamp(-922337203685477);
          to_timestamp           
---------------------------------
 294247-01-10 12:00:54.775808+08
(1 row)

postgres=> select to_timestamp(-92233720368547);
          to_timestamp           
---------------------------------
 294247-01-10 12:00:54.775808+08
(1 row)

postgres=> select to_timestamp(-9223372036854);
         to_timestamp         
------------------------------
 294247-01-10 12:00:55.552+08
(1 row)

postgres=> select to_timestamp(-922337203685);
ERROR:  timestamp out of range
postgres=> select to_timestamp(-92233720368);
          to_timestamp           
---------------------------------
 0954-03-26 09:50:36+07:43:24 BC
(1 row)

postgres=> select to_timestamp(-9223372036);
         to_timestamp         
------------------------------
 1677-09-21 07:56:08+07:43:24
(1 row)
Run Code Online (Sandbox Code Playgroud)

(也许与to_timestamp占用一倍的事实相关,即使时间戳这些天存储为整数?).

我认为让时间戳范围成为任何时间戳都不会出错,这可能是最明智的.毕竟,有效时间戳的范围不是连续的:

postgres=> SELECT TIMESTAMP '2000-02-29';
      timestamp      
---------------------
 2000-02-29 00:00:00
(1 row)

postgres=> SELECT TIMESTAMP '2001-02-29';
ERROR:  date/time field value out of range: "2001-02-29"
LINE 1: SELECT TIMESTAMP '2001-02-29';
Run Code Online (Sandbox Code Playgroud)

所以你不能假设只是因为一个值在两个有效时间戳之间,它是自己有效的.


Chr*_*ers 7

最早的时间戳是'-infinity'.这是一个特殊的价值.另一边是'无限',它比任何特定的时间戳晚.

我不知道如何以编程方式得到这个.我只是使用硬编码的值,你可能使用NULL的方式.这意味着你必须在客户端处理无限.