postgresql 实现计算日期间隔排除周末节假日方案

news/2024/7/9 22:12:10 标签: postgresql, 数据库

前置条件:需要维护一张节假日日期表。例如创建holiday表保存当年假期日期

CREATE TABLE `holiday` (
	`id` BIGINT(10) ZEROFILL NOT NULL DEFAULT 0,
	`day` TIMESTAMP NULL DEFAULT NULL,
	PRIMARY KEY (`id`)
)
COMMENT='假期表'
COLLATE='utf8mb4_0900_ai_ci'
;

返回日期为xx日xx时xx分格式,可以在此基础上调整格式

-- FUNCTION: public.get_timedelay(timestamp with time zone, timestamp with time zone)

-- DROP FUNCTION IF EXISTS public.get_timedelay(timestamp with time zone, timestamp with time zone);

CREATE OR REPLACE FUNCTION public.get_timedelay(
	starttime timestamp with time zone,
	endtime timestamp with time zone)
    RETURNS text
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$
DECLARE
	 v_return  varchar;--返回间隔时间 xx日xx时xx分
	 v_minute  integer;--间隔分钟
	 v_hour integer;
	 v_temp_minute integer;
	 v_temp_hour integer;
	 v_day integer; --间隔天数
	 v_all numeric;
	 v_counter integer;
	 v_end_weekend integer;
	 v_weekend integer;--周一_周日 1_6_0
	 v_holiday numeric;--匹配节假日天数
	 v_is_weekend boolean; --是否周末
	 v_is_holiday boolean; --是否节假日
BEGIN
		--计算时间间隔天数
		select ceil(DATE_PART('epoch', endtime::timestamp - starttime::TIMESTAMP)/60/60/24) into v_all;
		--减去周末、节假日
		v_end_weekend := cast(EXTRACT(DOW FROM (endtime)) as int);
		v_day := 0;
		v_hour := 0;
		v_minute := 0;
		v_counter := 0;
		while v_counter <= v_all loop
		   v_temp_minute := 0;
		   v_temp_hour  := 0;
		   v_is_weekend := FALSE;
		   v_is_holiday := FALSE;
			--判断该日期为周几
			v_weekend := v_end_weekend-v_counter%7;
			if v_weekend < 0 then
			   v_weekend := v_weekend + 7;
			end if;
			if v_weekend = 6 or v_weekend = 0 then
				v_is_weekend := true;
			end if;
			--判断该日期是否为节假日
			--日期表
			SELECT COUNT(*) FROM holiday WHERE Date(endtime) - DATE(day) - v_counter  = 0 INTO v_holiday;
			if v_is_weekend = false and v_holiday > 0 then
				v_is_holiday := true;
			end if;
			--累计时长
			if v_is_weekend = false AND v_is_holiday = false then
			   if v_counter = 0  then
			      v_minute := cast(date_part('minute', endtime::TIMESTAMP) as int);
			      v_hour := cast(date_part('hour', endtime::TIMESTAMP) as int);
			   elseif v_counter = v_all then
			      v_temp_minute := 60 - cast(date_part('minute', endtime::TIMESTAMP) as int);
			      v_temp_hour := 23 - cast(date_part('hour', endtime::TIMESTAMP) as int);
			      v_minute := (v_minute+v_temp_minute) % 60;
			      v_temp_hour := v_temp_hour+FLOOR((v_minute+v_temp_minute)/60);
			      v_hour := (v_hour+v_temp_hour) % 24;
			      v_day := v_day + FLOOR((v_hour+v_temp_hour) / 24);
				else
			   	v_day := v_day + 1;
			   end if;
			end if;
			v_counter:= v_counter+1;
		end loop;
		--处理返回日期
		v_return := '';
	
		--返回日、时、分方案
		if v_day > 0 then
		  v_return := concat(v_return, v_day,'日');
		end if;
		if v_hour > 0 then
		  v_return := concat(v_return, v_hour,'时');
		end if;
		if v_minute > 0 then
		  v_return := concat(v_return,v_minute,'分');
		end if;
	 
  RETURN v_return;
	
	EXCEPTION 
	WHEN OTHERS THEN
		RETURN SQLERRM;
	
END;
$BODY$;

ALTER FUNCTION public.get_timedelay(timestamp with time zone, timestamp with time zone)
    OWNER TO postgres;


http://www.niftyadmin.cn/n/5175274.html

相关文章

MySQL数据库干货_25——Properties文件的使用

Properties文件的使用 properties文件介绍 后缀properties的文件是一种属性文件。这种文件以keyvalue格式存储内容。Java中可以使用Properties工具类来读取这个文件。项目中会将一些配置信息放到properties文件中&#xff0c;所以properties文件经常作为配置文件来使用。 Pr…

MobileSAM论文笔记

摘要 自Meta研究团队发布SAM&#xff08;Segment Anything Model&#xff09;项目依赖&#xff0c;因其令人惊艳的零样本迁移特性和与其他视觉应用兼容的高通用性&#xff0c;引起了极大的关注。由于大多数类似的应用都需要运行在资源限制的边缘设备&#xff0c;如手机&#x…

TS 枚举、泛型、类、Partial和Required

1、枚举 枚举的作用很简单&#xff0c;就是用来列举数据&#xff0c;管理一系列数据的&#xff0c;让数据分类更加直观和可读&#xff0c;利于维护。 enum Status {success 200,fail 500 }let code:string|number 200; if( code Status.success ) {console.log("成功…

web网站 固定的邀请码字符 能被爬虫爬取吗?动态改变邀请码的字符是不是可以避免爬虫爬取或数据泄露

无论邀请码字符是固定的还是动态改变的&#xff0c;都无法完全避免爬虫爬取或数据泄露的风险。以下是一些要考虑的因素&#xff1a; 爬虫技术的发展&#xff1a;爬虫技术不断发展&#xff0c;可以智能地解析和获取网页内容。即使邀请码字符是固定的&#xff0c;高级爬虫仍然可以…

文生图模型测评之HPS v2

文章目录 1. 简介2. HPD v22.1 相关数据集介绍2.2 HPD v2 的构建2.2.1 prompt collection2.2.2 image collection2.2.3 preference annotation3. Human Preference Score v23.1 构建模型3.2 实验结果4. 结论及局限性论文链接:Human Preference Score v2: A Solid Benchmark fo…

【Linux】Linux动态库和静态库

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;Linux &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【Linux】…

3165:练27.2 布纳特难题《信息学奥赛一本通编程启蒙(C++版)》

3165&#xff1a;练27.2 布纳特难题《信息学奥赛一本通编程启蒙&#xff08;C版&#xff09;》 3165&#xff1a;练27.2 布纳特难题 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 2163 通过数: 1752 【题目描述】 德国“数学王子”高斯在10岁时便解答了布纳特老师出的难题&…

C51--PC通过串口(中断)点亮LED

B4中的&#xff1a;REN允许 / 禁止串行接收控制位 REN 1为允许串行接收状态。 接收数据必须开启。所以SCON&#xff1a;0101 0000 &#xff1b;即0x50 如何知道数据已经接收 RI位&#xff1a;当收到数据后 RI 1&#xff08;由硬件置一&#xff09; 硬件置一后必须用软件…