如何将时间戳上下调整到最近的分钟?

是否有一个 postgreql 函数,它将返回一个四舍五入到最近分钟的时间戳?输入值是一个时间戳,返回值应该是一个时间戳。

80456 次浏览

使用内置函数 date_trunc(text, timestamp),例如:

select date_trunc('minute', now())

编辑: 这将截断到 最近的分钟。为了得到 圆的结果,首先在时间戳上添加30秒,例如:

select date_trunc('minute', now() + interval '30 second')

这将返回 最近的分钟。

有关更多信息,请参见 Postgres 日期/时间函数和运算符

回答一个类似的问题,

“ ... 到 最近的分钟间隔”(1分钟、5分钟、10分钟等)

CREATE FUNCTION round_minutes(TIMESTAMP WITHOUT TIME ZONE, integer)
RETURNS TIMESTAMP WITHOUT TIME ZONE AS $$
SELECT
date_trunc('hour', $1)
+  cast(($2::varchar||' min') as interval)
* round(
(date_part('minute',$1)::float + date_part('second',$1)/ 60.)::float
/ $2::float
)
$$ LANGUAGE SQL IMMUTABLE;


CREATE FUNCTION round_minutes(TIMESTAMP WITHOUT TIME ZONE, integer,text)
RETURNS text AS $$
SELECT to_char(round_minutes($1,$2),$3)
$$ LANGUAGE SQL IMMUTABLE;


SELECT round_minutes('2010-09-17 16:23:12', 5);
-- 2010-09-17 16:25:00


SELECT round_minutes('2010-09-17 16:23:12', 10, 'HH24:MI');
-- 16:20

改编自 http://wiki.postgresql.org/wiki/Round_time和“精确的一轮”,如@CrowMagzzy 所示。

在尝试使用 Peter 上面的答案来创建天花板和地板函数时,我发现在调用舍入函数时也必须考虑秒数。这里是我的函数集,它们将用于圆形、地板和天花板的时间戳。

CREATE OR REPLACE FUNCTION round_minutes( TIMESTAMP WITHOUT TIME ZONE, integer)
RETURNS TIMESTAMP WITHOUT TIME ZONE AS $$
SELECT date_trunc('hour', $1) + (cast(($2::varchar||' min') as interval) * round( (date_part('minute',$1)::float + date_part('second',$1)/ 60.)::float / cast($2 as float)))
$$ LANGUAGE SQL IMMUTABLE STRICT;


CREATE OR REPLACE FUNCTION floor_minutes( TIMESTAMP WITHOUT TIME ZONE, integer )
RETURNS TIMESTAMP WITHOUT TIME ZONE AS $$
SELECT round_minutes( $1 - cast((($2/2)::varchar ||' min') as interval ), $2 );
$$ LANGUAGE SQL IMMUTABLE STRICT;


CREATE OR REPLACE FUNCTION ceiling_minutes( TIMESTAMP WITHOUT TIME ZONE, integer )
RETURNS TIMESTAMP WITHOUT TIME ZONE AS $$
SELECT round_minutes( $1 + cast((($2/2)::varchar ||' min') as interval ), $2 );
$$ LANGUAGE SQL IMMUTABLE STRICT;

四舍五入一个时间戳

CREATE or replace FUNCTION date_round_down(base_date timestamptz, round_interval INTERVAL)
RETURNS timestamptz AS $BODY$
SELECT TO_TIMESTAMP(EXTRACT(epoch FROM date_trunc('hour', $1))::INTEGER + trunc((EXTRACT(epoch FROM $1)::INTEGER - EXTRACT(epoch FROM date_trunc('hour', $1))::INTEGER) / EXTRACT(epoch FROM $2)::INTEGER) * EXTRACT(epoch FROM $2)::INTEGER)
$BODY$ LANGUAGE SQL STABLE;


SELECT date_round_down('2017-06-02 16:39:35', '15 minutes') -- 2017-06-02 16:30:35