PostgreSQL 当月最后一天的工作日 , 计算日期是星期几

可以用pg自带函数select extract(dow from current_date),之所以没用主要是展示一下通过数学方法计算日期的原理.

drop function if exists getDateWeek(date);
drop function if exists intervalDay(date);
drop function if exists getMonMaxDay(integer,integer);
drop function if exists getMonMaxDate(integer,integer);
/****************************************************************************************
    判断年份是闰年还是平年
drop function if exists isleap(integer);
select isleap(2018);
****************************************************************************************/
create or replace function  isleap(integer)
  returns boolean
as $$
	select (($1 % 4) = 0 and (($1 % 100) <> 0 or ($1 % 400) = 0))
$$ language sql immutable strict;
/****************************************************************************************
    根据年度和月份获取本月的最后一天
drop function if exists getDateWeek(integer,integer);
drop function if exists getMonMaxDate(integer,integer);
select getMonMaxDay(2018,8);
select getMonMaxDate(2018,8);
****************************************************************************************/
create or replace function getMonMaxDay(iyear integer,imonth integer)
  returns integer
as $$
	select 
		(case when 2=$2 then 
	 		(case when isleap($1) then
	 			29
			else
	 			28
	 		end)
		 when 4=$2 or 6=$2 or 9=$2 or 11=$2 then
	 		30
		 else
	 		31
		end)
$$ language sql immutable strict;

create or replace function getMonMaxDate(iyear integer,imonth integer)
  returns date
as $$
	select make_date( iyear,imonth,
		(case when 2=$2 then 
	 		(case when isleap($1) then
	 			29
			else
	 			28
	 		end)
		 when 4=$2 or 6=$2 or 9=$2 or 11=$2 then
	 		30
		 else
	 		31
		end));
$$ language sql immutable strict;

/****************************************************************************************
    与1970-1-1间隔多少天
drop function if exists intervalDay(date);
select intervalDay(current_date);
****************************************************************************************/
create or replace function intervalDay(date)
  returns integer
as $$
	select (extract(epoch from $1) / 86400)::integer;
$$ language sql immutable strict;
/****************************************************************************************
    获取日期是星期几
        1970-1-1是星期4
        返回结果中的0表示星期天
drop function if exists getDateWeek(date);
select getMonLastDayWeek('2019-08-1'::date);
****************************************************************************************/
create or replace function getDateWeek(date)
  returns integer
as $$
	with cte as (
		select ( ( 4 + intervalDay($1) ) % 7 ) as val
	) select ( case when val < 0 then
			7+val
		else
			val
		end)
	from cte
$$ language sql immutable strict;

使用方法

--检查函数是否正确
with cte as(
    select to_timestamp(val*86400) as dt from generate_series(-100,100) as val
)select getDateWeek(dt::date),dt from cte;

--获取2017年6月的最后一天是星期几
select getDateWeek(getMonMaxDate(2017,6));

猜你喜欢

转载自blog.csdn.net/kmblack1/article/details/82414602
今日推荐