Postgres: làm thế nào để bạn làm tròn dấu thời gian lên hoặc xuống đến phút gần nhất?


83

Có hàm postgresql sẽ trả về dấu thời gian làm tròn đến phút gần nhất không? Giá trị đầu vào là dấu thời gian và giá trị trả về phải là dấu thời gian.

Câu trả lời:


130

Sử dụng chức năng tích hợp sẵn date_trunc(text, timestamp), ví dụ:

select date_trunc('minute', now())

Chỉnh sửa: Điều này cắt ngắn đến phút gần đây nhất . Để có kết quả làm tròn , trước tiên hãy thêm 30 giây vào dấu thời gian, ví dụ:

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

Điều này trả về phút gần nhất .

Xem Các chức năng và toán tử Ngày / Giờ của Postgres để biết thêm thông tin


20
+1 cho mẹo thông minh là thêm một nửa khoảng và sau đó cắt bớt.
KS tháng 1,

14

Trả lời cho một câu hỏi tương tự (và chung chung hơn),

"... đến khoảng phút gần nhất " (1 phút, 5 phút, 10 phút, v.v.)

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

Phỏng theo http://wiki.postgresql.org/wiki/Round_time và theo "vòng chính xác" như @CrowMagnumb đã hiển thị.


6

Khi cố gắng sử dụng câu trả lời của Peter ở trên để tạo các hàm trần và sàn, tôi thấy rằng bạn cũng phải tính đến số giây khi gọi hàm làm tròn. Đây là bộ hàm của tôi sẽ đánh dấu thời gian làm tròn, sàn và trần.

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;

Nhờ vào phần sửa (!) Và phần mở rộng: bây giờ chúng tôi có một thư viện "phút gần đúng" hoàn chỉnh. Tái bút: Tôi nghĩ bạn có thể thêm một int DEFAULT 5(tham số thứ hai) để đơn giản hóa việc sử dụng thường xuyên nhất.
Peter Krauss

Ops, một vấn đề khác: sử dụng LANGUAGE SQL IMMUTABLE.
Peter Krauss

3

để làm tròn một dấu thời gian

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

Tuy nhiên, nó không làm tròn 35 giây, điều mà tôi nghĩ là mong đợi
Moody_Mudskipper

tôi đã thử sử dụng điều này để làm tròn thành 2 giờ một lần. không hoạt động.
jpro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.