欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-17 21:39:42
...

可以用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));