Можно рассчитать простым способом.
Если ваши два параметра уже являются рабочими днями, вы можете просто вернуть их разницу в секундах, минус 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