如何获得一个月的天数?

时间:2011-08-03 13:22:49

标签: postgresql datetime date-arithmetic

我想在Postgres中获得以下内容:

select day_in_month(2);

预期产出:

28

Postgres有没有内置的方法来做到这一点?

6 个答案:

答案 0 :(得分:33)

SELECT  
    DATE_PART('days', 
        DATE_TRUNC('month', NOW()) 
        + '1 MONTH'::INTERVAL 
        - '1 DAY'::INTERVAL
    )

NOW()替换为任何其他日期。

答案 1 :(得分:2)

使用智能"技巧"从月份的最后一天开始提取部分,为demonstrated by Quassnoi。但它可以更简单/更快:

SELECT extract(days FROM date_trunc('month', now()) + interval '1 month - 1 day');

原理

extract是标准SQL,因此可能更好,但它在内部解析为与date_part()相同的函数。 The manual:

  

date_part函数模仿传统的Ingres,相当于SQL标准函数extract

但我们只需添加 a interval 。 Postgres允许一次使用多个时间单位。 The manual:

  可以使用以下详细语法编写

interval个值:

     

[@] quantity unit [ quantity unit ...] [ direction ]

     

其中 quantity 是一个数字(可能已签名); unit microsecond,   millisecondsecondminutehourdayweekmonthyear,{{ 1}},   decadecentury或这些单位的缩写或复数形式;

ISO 8601 or standard SQL format也被接受。无论哪种方式,the manual again

  

内部millennium值存储为月,日和秒。   这样做是因为一个月中的天数变化,一天变化   如果夏令时调整,可以有23或25小时   参与其中。月份和日期字段是整数,而秒数   字段可以存储分数。

(输出/显示取决于setting of IntervalStyle。)

以上示例使用默认Postgres格式interval。这些也是有效的(虽然可读性较差):

interval '1 month - 1 day'

IS0 8601格式

interval '1 mon - 1 d' -- unambiguous abbreviations of time units are allowed

标准SQL格式

interval '0-1 -1 0:0'

都一样。

答案 2 :(得分:1)

请注意,由于闰年,day_in_month(2)的预期输出可能是29。您可能希望传递日期而不是int。

另外,请注意夏令时:删除时区或者某些monthes计算可能是错误的(CET / CEST中的下一个示例):

SELECT  DATE_TRUNC('month', '2016-03-12'::timestamptz) + '1 MONTH'::INTERVAL
      - DATE_TRUNC('month', '2016-03-12'::timestamptz) ;
------------------
 30 days 23:00:00

SELECT  DATE_TRUNC('month', '2016-03-12'::timestamp) + '1 MONTH'::INTERVAL
      - DATE_TRUNC('month', '2016-03-12'::timestamp) ;
----------
 31 days

答案 3 :(得分:0)

这也有效。

WITH date_ AS (SELECT your_date AS d)
SELECT d + INTERVAL '1 month' - d FROM date_;

或者只是:

SELECT your_date + INTERVAL '1 month' - your_date;

这两个返回 interval ,而不是整数

答案 4 :(得分:0)

您可以编写一个函数:

CREATE OR REPLACE FUNCTION get_total_days_in_month(timestamp)
RETURNS decimal
IMMUTABLE
AS $$
  select cast(datediff(day, date_trunc('mon', $1), last_day($1) + 1) as decimal)
$$ LANGUAGE sql;

答案 5 :(得分:-1)

SELECT cnt_dayofmonth(2016, 2);  -- 29


create or replace function cnt_dayofmonth(_year int, _month int)
returns int2 as
$BODY$
-- ZU 2017.09.15, returns the count of days in mounth, inputs are year and month
declare 
    datetime_start date := ('01.01.'||_year::char(4))::date;
    datetime_month date := ('01.'||_month||'.'||_year)::date;
        cnt int2;
begin 
  select extract(day from (select (datetime_month + INTERVAL '1 month -1 day'))) into cnt;

  return cnt;
end;
$BODY$
language plpgsql;