134 votes

Postgres : comment arrondir un horodatage à la minute supérieure ou inférieure ?

Existe-t-il une fonction postgresql qui renvoie un horodatage arrondi à la minute la plus proche ? La valeur d'entrée est un horodatage et la valeur de retour devrait être un horodatage.

231voto

Bohemian Points 134107

Utilisez la fonction intégrée date_trunc(text, timestamp) par exemple :

select date_trunc('minute', now())

Edit : Ceci est tronqué à la le plus récent minute. Pour obtenir un arrondi le résultat, ajoutez d'abord 30 secondes à l'horodatage, par exemple :

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

Cela renvoie le le plus proche minute.

Voir Fonctions et opérateurs de date et d'heure de Postgres pour plus d'informations

23voto

Peter Krauss Points 1888

Réponse à une question similaire (et plus générique),

"... au intervalle de la minute la plus proche "(1 minute, 5 minutes, 10 minutes, etc.)

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

Adapté de http://wiki.postgresql.org/wiki/Round_time et au "tour exact" comme l'a montré @CrowMagnumb.

8voto

Crow Magnumb Points 901

En essayant d'utiliser la réponse de Peter ci-dessus pour créer des fonctions de plafond et de plancher, j'ai découvert qu'il fallait également tenir compte des secondes lors de l'appel de la fonction d'arrondi. Voici donc mes ensembles de fonctions qui arrondissent les timbres, les planchers et les plafonds.

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;

5voto

James De Souza Points 153

Pour arrondir un horodatage à la baisse

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X