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;
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;
7条答案
按热度按时间mgdq6dx11#
字符串
将
NOW()
替换为任何其他日期。pn9klfpd2#
使用聪明的“技巧”从月份的最后一个日期中提取 day 部分,作为demonstrated by Quassnoi。但它可以更简单/更快一点:
字符串
基本原理
extract
是标准的SQL,所以可能更好,但它在内部解析为与date_part()
相同的函数。手册:date_part
函数是在传统的Ingres上建模的,相当于SQL标准函数extract
:但我们只需要添加a * 单个 *
interval
。Postgres允许一次使用多个时间单位。手册:interval
值可以使用以下详细语法编写:[@]
quantity unit
[
quantity unit
...] [
direction
]
其中 *
quantity
* 是一个数字(可能签署);*unit
* 为microsecond
、millisecond
、second
、minute
、hour
、day
、week
、month
、year
、decade
、century
、millennium
,或这些单元的缩写或复数;ISO 8601或标准SQL格式也被接受。无论哪种方式,手册再次:
interval
的值在内部存储为月、日和秒。这样做是因为一个月中的天数不同,如果涉及夏令时调整,一天可以有23或25小时。月和日字段是整数,而秒字段可以存储分数。(输出/显示取决于
IntervalStyle
的设置。)上面的例子使用default Postgres format:
interval '1 month - 1 day'
。这些也是有效的(虽然可读性较差):型
IS 0 8601格式:
型
标准SQL格式:
型
都一样
yjghlzjz3#
注意,由于闰年的原因,day_in_month(2)的预期输出可能是29。您可能希望传递一个日期而不是整数。
此外,要注意夏令时:删除时区,否则某些月份的计算可能是错误的(下一个例子在CET / CEST):
字符串
mv1qrgav4#
字符串
减去两个时间戳总是会产生一个以天为单位的时间间隔,我们不会得到一个以月或年为单位的答案,因为这些时间段的长度是可变的。
olqngx595#
这个也行。
字符串
或者只是:
型
这两个函数返回 interval,而不是 integer。
kzipqqlq6#
字符串
ippsafx77#
你可以写一个函数:
字符串