PostgreSQL 以毫秒为单位为 postgres 预先创建的日期舍入时间戳秒数

Ant*_*ony 5 sql postgresql time timestamp zone

我有一个查询,不幸的是必须比较 2 个时间戳。PHP date() 函数为 DB 提供一个时间戳,存储为不带时区的时间戳,因此该日期没有添加毫秒。另一个是带时区的 PG 时间戳。所以两个日期都已经被创建并插入到表中,这里是日期的一个例子:

没有时区的时间戳 = 2012-09-19 18:13:26

PG 的时间戳与时区 = 2012-09-19 18:13:26.893878-04

我可以投射 PG date::timestamp(0) 这让我接近但正如预期的那样日期被四舍五入;2012-09-19 18:13:27

所以我的问题是如何让秒数四舍五入?

Dan*_*ité 7

要向下舍入到第二个,请使用date_trunc('seconds', :timestamp)

例子:

select date_trunc('seconds', '2012-09-19 18:13:26.893878-04'::timestamp)
  = '2012-09-19 18:13:26'::timestamp;
Run Code Online (Sandbox Code Playgroud)

这产生t(真实)


Cra*_*ger 3

比较时间戳的相等性很少能起到很好的作用。如果这两个时间戳是在 处获取的怎么办2012-09-19 18:13:26.99999999?时钟抖动、调度程序抖动、执行时间差异等可能并且经常会将一个延迟到下一秒。它也不必非常接近边缘才会发生。你可以尝试 hack

相反,与窄范围进行比较;说2秒:

SET timezone = '+04:00';

SELECT (TIMESTAMP '2012-09-19 18:13:26')::timestamptz 
       BETWEEN TIMESTAMPTZ '2012-09-19 18:13:26.893878-04' - INTERVAL '1' SECOND 
           AND TIMESTAMPTZ '2012-09-19 18:13:26.893878-04' + INTERVAL '1' SECOND;
Run Code Online (Sandbox Code Playgroud)

我不确定你可以使用比这更粗糙的东西,因为你的 PHP 时间戳的精度是 1 秒。

如果您确定 PHP 总是截断时间戳(向下舍入),而不是四舍五入到即使它捕获时间戳,您可以通过调整包围间隔来粗略地纠正这一点。例如,尝试 1 秒间隔(给定 PHP 时间戳精度时可以测试的最窄间隔),并假设 PHP 总是向下截断时间戳:

SELECT (TIMESTAMP '2012-09-19 18:13:26')::timestamptz 
       BETWEEN TIMESTAMPTZ '2012-09-19 18:13:26.893878-04' - INTERVAL '1' SECOND 
           AND TIMESTAMPTZ '2012-09-19 18:13:26.893878-04';
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我会每边至少再添加 0.1 秒以确保:

SELECT (TIMESTAMP '2012-09-19 18:13:26')::timestamptz 
       BETWEEN TIMESTAMPTZ '2012-09-19 18:13:26.893878-04' - INTERVAL '1.1' SECOND 
           AND TIMESTAMPTZ '2012-09-19 18:13:26.893878-04' + INTERVAL '0.1' SECOND;
Run Code Online (Sandbox Code Playgroud)

如果您确实坚持测试相等性,请使用:

regress=# SELECT date_trunc('second', TIMESTAMPTZ '2012-09-19 18:13:26.893878-04');
       date_trunc       
------------------------
 2012-09-19 18:13:26-04
(1 row)
Run Code Online (Sandbox Code Playgroud)

但请注意,测试两个单独捕获的时间戳是否相等是危险且错误的。