计算postgresql上两个时间戳之间的月份?

Gae*_*anZ 26 postgresql

我想计算两个日期之间的月数.

做:

SELECT TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40';
Run Code Online (Sandbox Code Playgroud)

返回:0年0月40日409天20小时0分0.00秒

所以:

SELECT extract(month from TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40');
Run Code Online (Sandbox Code Playgroud)

返回0.

Ang*_*dar 29

age function returns interval:

age(timestamp1, timestamp2)
Run Code Online (Sandbox Code Playgroud)

Then we try to extract year and month out of the interval and add them accordingly:

select extract(year from age(timestamp1, timestamp2)) * 12 +
extract(month from age(timestamp1, timestamp2))
Run Code Online (Sandbox Code Playgroud)


Mat*_*sOl 14

age函数给出了合理的间隔:

SELECT age(TIMESTAMP '2012-06-13 10:38:40', TIMESTAMP '2011-04-30 14:38:40');
Run Code Online (Sandbox Code Playgroud)

返回1 year 1 mon 12 days 20:00:00,并且您可以轻松地使用它EXTRACT来计算月数:

SELECT EXTRACT(YEAR FROM age) * 12 + EXTRACT(MONTH FROM age) AS months_between
FROM age(TIMESTAMP '2012-06-13 10:38:40', TIMESTAMP '2011-04-30 14:38:40') AS t(age);
Run Code Online (Sandbox Code Playgroud)


小智 11

请注意,当您尝试使用日历月差时,@ram@angelin投票最多的答案是不准确的。

select extract(year from age(timestamp1, timestamp2))*12 + extract(month from age(timestamp1, timestamp2))
Run Code Online (Sandbox Code Playgroud)

例如,如果您尝试执行以下操作:

select extract(year from age('2018-02-02'::date, '2018-03-01'::date))*12 + extract(month from age('2018-02-02'::date , '2018-03-01'::date))
Run Code Online (Sandbox Code Playgroud)

结果将为 0,但无论日期之间的天数如何,从 3 月到 2 月之间的月份都应为 1。

所以公式应该如下所示,我们从timestamp1和timestamp2开始:

((year2 - year1)*12) - month1 + month2 = 两个时间戳之间的日历月

在 pg 中将被翻译为:

select ((extract('years' from '2018-03-01 00:00:00'::timestamp)::int -  extract('years' from '2018-02-02 00:00:00'::timestamp)::int) * 12) 
    - extract('month' from '2018-02-02 00:00:00'::timestamp)::int + extract('month' from '2018-03-01 00:00:00'::timestamp)::int;
Run Code Online (Sandbox Code Playgroud)

您可以创建一个函数,如:

CREATE FUNCTION months_between (t_start timestamp, t_end timestamp)
RETURNS integer
AS $$
select ((extract('years' from $2)::int -  extract('years' from $1)::int) * 12) 
    - extract('month' from $1)::int + extract('month' from $2)::int
$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
Run Code Online (Sandbox Code Playgroud)


Mar*_*rco 8

如果您将多次执行此操作,则可以定义以下函数:

CREATE FUNCTION months_between (t_start timestamp, t_end timestamp)
    RETURNS integer
    AS $$
        SELECT
            (
                12 * extract('years' from a.i) + extract('months' from a.i)
            )::integer
        from (
            values (justify_interval($2 - $1))
        ) as a (i)
    $$
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;
Run Code Online (Sandbox Code Playgroud)

这样你就可以了

SELECT months_between('2015-01-01', now());
Run Code Online (Sandbox Code Playgroud)


ati*_*ruz 6

SELECT date_part ('year', f) * 12
      + date_part ('month', f)
FROM age ('2015-06-12', '2014-12-01') f
Run Code Online (Sandbox Code Playgroud)

结果:6 个月


Nav*_*dav 2

给出两个日期的月份之差

   SELECT ((extract( year FROM TIMESTAMP '2012-06-13 10:38:40' ) - extract( year FROM TIMESTAMP '2011-04-30 14:38:40' )) *12) + extract(MONTH FROM TIMESTAMP '2012-06-13 10:38:40' ) - extract(MONTH FROM TIMESTAMP '2011-04-30 14:38:40' );
Run Code Online (Sandbox Code Playgroud)

结果:14

必须分别提取两个日期的月份,然后提取两个结果的差异