[英]How to calculate difference between two dates in seconds during business hours for business days SQL Server?
我喜欢在 SQL Server 中获得两个工作日之间的秒数差异。 我们有日期表包含 IsWorkingDay 标志,如果结束日期为空,那么它应该默认为 getdate()。 工作日从早上 8 点开始,到下午 4:30 结束。
我有以下查询,在其他部分需要帮助。
@StartDate 和 @EndDate 并不总是在工作日。 如果@StartDate 是在任何周末或假日,它应该在上午 8:00 累积到下一个工作日。 如果@EndDate 是在任何周末或假日,它应该在下午 4:30 累积到最后一个工作日。
CREATE FUNCTION TimeDiffInSeconds
(
@Startdate DATETIME
,@EndDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE @WorkSeconds INT = 0;
DECLARE @Reverse BIT;
DECLARE @StartHour FLOAT = 8
DECLARE @EndHour FLOAT = 16.50
IF @Startdate > @EndDate
BEGIN
DECLARE @TempDate DATETIME = @Startdate;
SET @Startdate = @EndDate;
SET @EndDate = @TempDate;
SET @Reverse = 1;
END;
ELSE
SET @Reverse = 0;
IF DATEPART(HH, @StartDate) < @StartHour
SET @StartDate = DATEADD(HOUR, @StartHour, DATEDIFF(DAY, 0, @StartDate));
IF DATEPART(HH, @StartDate) >= @EndHour + 1
SET @StartDate = DATEADD(HOUR, @StartHour + 24, DATEDIFF(DAY, 0, @StartDate));
IF DATEPART(HH, @EndDate) >= @EndHour + 1
SET @EndDate = DATEADD(HOUR, @EndHour, DATEDIFF(DAY, 0, @EndDate));
IF DATEPART(HH, @EndDate) < @StartHour
SET @EndDate = DATEADD(HOUR, @EndHour - 24, DATEDIFF(DAY, 0, @EndDate));
IF @Startdate > @EndDate
RETURN 0;
IF DATEDIFF(DAY, @StartDate, @EndDate) <= 0
BEGIN
IF @Startdate <> (SELECT date_id FROM Final.Date WHERE IsWorkingDay = 0)
SET @WorkSeconds = DATEDIFF(ss, @StartDate, @EndDate); -- Calculate difference
ELSE RETURN 0;
END;
ELSE
--need help
RETURN @WorkSeconds;
END
可以用简单的方法计算。
如果您的两个参数已经是工作日,那么您可以以秒为单位返回它们的差异,减去每天差异(每次跨越午夜边界时)的 15.5 小时(16:30 到 08:00),减去 8,5 小时( 8:00 到 16:30) 在两个日期之间的每个非工作日。
PS:我已经更新了答案,所以我们现在首先检查@StartDate 和@EndDate 是否是正确的工作日期时间,如果不是,那么我们将它们移动到正确的日期时间。 之后,您可以应用前面描述的以秒为单位的工作时间计算。
CREATE FUNCTION TimeDiffInSeconds
(
@Startdate datetime,
@EndDate datetime
)
RETURNS INT
AS
BEGIN
set @EndDate = coalesce(@EndDate, getdate());
-- We check that @StartDate is a working datetime, and if not we set it to the next one
if convert(time, @StartDate) < convert(time, '08:00')
begin
set @StartDate = convert(datetime, convert(date, @StartDate)) +
convert(datetime, '08:00')
end
if convert(time, @StartDate) > convert(time, '16:30') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, @StartDate)) = 0
begin
select top 1 @StartDate = convert(datetime, date_id) +
convert(datetime, '08:00')
from Final.Date
where date_id > @StartDate and IsWorkingDay = 1
order by date_id
end
-- We check that @EndDate is a working datetime, and if not we set it to the last one
if convert(time, @EndDate) > convert(time, '16:30')
begin
set @EndDate = convert(datetime, convert(date, @EndDate)) +
convert(datetime, '16:30')
end
if convert(time, @EndDate) < convert(time, '08:00') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, @EndDate)) = 0
begin
select top 1 @EndDate = convert(datetime, date_id) +
convert(datetime, '16:30')
from Final.Date
where date_id < @EndDate and IsWorkingDay = 1
order by date_id desc
end
-- We return the working time difference in seconds between @StartDate and @EndDate
RETURN datediff(second, @StartDate, @EndDate) -
((15.5 * datediff(day, @StartDate, @EndDate) * 60 * 60) -
(8.5 * (select count(*)
from Final.Date
where IsWorkingDay = 0 and
(date_id between @StartDate and @EndDate or date_id between @EndDate and @StartDate)
) * 60 * 60));
END
在线测试: https : //rextester.com/FWR14059
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.