问题说明:任给出两个时间(开始时间<结束时间),算出这个两个时间 的工作日时间差,节假日不算,非工作时间不算(例某公司上午上班时间8:30 - 12:00,下午上班时间:13:30 - 18:00,即只在这个排班时间 间的时间差)
问题应用考勤计算、流程耗时计算、工作日天数计算等
解题思路
- 最后要的结果是时间差,用自定义函数解决
- 分两种考虑,开始时间和结束时间在同一天和不在同一天
- 开始/结束时间在同一天,分情况(一共16种,下面列出)计算
- 开始/结束时间不在同一天,先计算两个时间间的工作日天数(不含首尾),再计算分别开始时间和结束时间所在工作日的 当天的时间差
- 本次将定义四个自定义函数:①get_WorkTime 主函数(会调用另外三个函数) ②get_WorkDay 计算两个日期的工作日天数(不含首尾) ③get_WorkStrTime 计算开始时间的工作时间(开始/结束时间不在同一天情况) ④get_WorkEndTime 计算结束时间的工作时间(开始/结束时间不在同一天情况)
准备工作
函数中会用到日历表用来判断某一个日期是否为工作日,表(T_Calendar)的格式如下:
问题开始
定义get_WorkTime 主函数
--------------------------创建自定义标量函数计算两个具体时间的工作日(8小时)时间差---------------------
CREATE FUNCTION [dbo].[get_WorkTime](@str_time datetime, @end_time datetime)
RETURNS int
AS
BEGIN
declare @am_str time, @am_end time
,@pm_str time ,@pm_end time
,@day_str_type varchar(100)
,@day_end_type varchar(100)
,@myresult int
--定义工作日上班时间段
set @am_str='08:30:00.00' set @am_end='12:00:00.00'
set @pm_str='13:30:00.00' set @pm_end='18:00:00.00'
----定义开始时间结束时间测试
--set @str_time='2018-11-06 17:59:00.00'
--set @end_time='2018-11-08 08:30:00.00'
set @day_str_type=
(select a.日期类型 from T_Calendar a
inner join (select cast(@str_time as date) as fz) b
on a.日期=b.fz)
set @day_end_type=
(select a.日期类型 from T_Calendar a
inner join (select cast(@end_time as date) as fz) b
on a.日期=b.fz)
-------------------------------------------------判断开始时间和结束时间是不是在同一天--------------------------------------------------
if(CONVERT(VARCHAR(10),@str_time, 120) = CONVERT(VARCHAR(10),@end_time, 120))
---------------------------------------------------开始和结束时间在同一天----------------------------