Der Ausdruck
age('2012-11-30 00:00:00'::timestamp, '2012-10-31 00:00:00'::timestamp)
ergibt 30 days
. Wir erwarten 1 month
da beide Werte auf die letzten Tage des Monats zeigen. Wenn wir 1 Tag zu den Werten hinzufügen, erhalten wir die ersten Tage des nächsten Monats und
age('2012-12-01 00:00:00'::timestamp, '2012-11-01 00:00:00'::timestamp)
wird uns wie erwartet 1 Monat geben. Lassen Sie uns also prüfen, ob wir zwei letzte Tage des Monats haben und in diesem Fall das Altersintervall der nächsten Tage zurückgeben. In anderen Fällen geben wir das Altersintervall der ursprünglichen Werte zurück:
create or replace function age_m (t1 timestamp, t2 timestamp)
returns interval language plpgsql immutable
as $$
declare
_t1 timestamp = t1+ interval '1 day';
_t2 timestamp = t2+ interval '1 day';
begin
if extract(day from _t1) = 1 and extract(day from _t2) = 1 then
return age(_t1, _t2);
else
return age(t1, t2);
end if;
end $$;
Einige Beispiele:
with my_table(date1, date2) as (
values
('2012-11-30 00:00:00'::timestamp, '2012-10-31 00:00:00'::timestamp),
('2012-12-31 00:00:00'::timestamp, '2012-10-31 00:00:00'::timestamp),
('2013-01-31 00:00:00'::timestamp, '2012-10-31 00:00:00'::timestamp),
('2013-02-28 00:00:00'::timestamp, '2012-10-31 00:00:00'::timestamp)
)
select *, age(date1, date2), age_m(date1, date2)
from my_table
date1 | date2 | age | age_m
---------------------+---------------------+----------------+--------
2012-11-30 00:00:00 | 2012-10-31 00:00:00 | 30 days | 1 mon
2012-12-31 00:00:00 | 2012-10-31 00:00:00 | 2 mons | 2 mons
2013-01-31 00:00:00 | 2012-10-31 00:00:00 | 3 mons | 3 mons
2013-02-28 00:00:00 | 2012-10-31 00:00:00 | 3 mons 28 days | 4 mons
(4 rows)