/*
This sample down below updating previous material an shown what's happened if you want to ADD more than 23 hours to a date:
*/
USE [REP]
GO
/****** Object: UserDefinedFunction [dbo].[fct_add_hours_depend_workshift_L-V_0830_1830] Script Date: 11/26/2018 3:22:37 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
UTILIZATION
SELECT
GETDATE () as crt_date
,[rep].[dbo].[fct_add_hours_depend_workshift_L-V_0830_1830]
(
GETDATE()
,number_of_hours_as_integer -- ex: 96
) as_expiration_date
ORIGINAL SOURCE:
https://stackoverflow.com/questions/1130721/t-sql-2005-adding-hours-to-a-datetime-field-with-the-result-within-working-hours
*/
ALTER FUNCTION [dbo].[fct_add_hours_depend_workshift_L-V_0830_1830]
(
@Date DATETIME,
@HrsAdd INT
)
RETURNS DATETIME
as
BEGIN
DECLARE @StartOfDay FLOAT,
@EndOfDay FLOAT
-- workshift declaration de la 8:30 la 18:30
SELECT @StartOfDay = 8.5,
@EndOfDay = 18.5
--fix up start date
--before start of day, move to start of day
IF ((CAST(@Date - DATEADD(dd,0, DATEDIFF(dd,0,@Date)) AS FLOAT) * 24) < @StartOfDay)
BEGIN
SET @Date = DATEADD(mi, @StartOfDay * 60, DATEDIFF(dd,0,@Date))
END
--after close of day, move to start of next day
IF ((CAST(@Date - DATEADD(dd,0, DATEDIFF(dd,0,@Date)) AS FLOAT) * 24) > @EndOfDay)
BEGIN
SET @Date = DATEADD(mi, @StartOfDay * 60, DATEDIFF(dd,0,@Date)) + 1
END
--move to monday if on weekend
WHILE DATENAME(dw, @Date) IN ('Saturday','Sunday')
BEGIN
SET @Date = @Date + 1
END
--get the number of hours to add and the total hours per day
DECLARE @HoursPerDay FLOAT
DECLARE @HoursAdd FLOAT
DECLARE @DateAdd DATETIME
/*
Pentru ca scriptul initial nu-ti permite sa adaugi mai mult de 23 ore am facut o modificare:
- daca trebuie sa adaug mai putin de 23 de ore merg pe clasicul definit de dezvoltator
- daca trebuie sa adaug mai mult de 23 ore fac impartirea la 23 cu rest : ex 96 impartit cu rest la 23 = 4 zile (de workshift L-V 8:30-18:30) si 4 ore (de workshift L-V 8:30-18:30) si voi folosi numai intregul sau daca vrei 96/23 si iau modulo
*/
-- Do I have to add more than 23 hours?
IF (@HrsAdd > 23)
BEGIN
SET @DateAdd = DATEADD
(dd,
@HrsAdd/23,
CAST('1900-01-01 00:00:00.000' as DATETIME)
)
END
ELSE
SET @DateAdd = CAST('1900-01-01 ' + CAST(@HrsAdd as NVARCHAR(2)) + ':00:00.000' as DATETIME)
SET @HoursAdd = DATEDIFF(hh, '1900-01-01 00:00:00.000', @DateAdd)
SET @HoursPerDay = @EndOfDay - @StartOfDay
--date the time of geiven day
DECLARE @CurrentHours FLOAT
SET @CurrentHours = CAST(@Date - DATEADD(dd,0, DATEDIFF(dd,0,@Date)) AS FLOAT) * 24
--if we stay in the same day, all is fine
IF (@CurrentHours + @HoursAdd <= @EndOfDay)
BEGIN
SET @Date = @Date + @DateAdd
END
ELSE
BEGIN
--remove part of day
SET @HoursAdd = @HoursAdd - (@EndOfDay - @CurrentHours)
--,ove to next day
SET @Date = DATEADD(dd,0, DATEDIFF(dd,0,@Date)) + 1
--loop day
WHILE @HoursAdd > 0
BEGIN
--add day but keep hours to add same
IF (DATENAME(dw,@Date) IN ('Saturday','Sunday'))
BEGIN
SET @Date = @Date + 1
END
ELSE
BEGIN
--add a day, and reduce hours to add
IF (@HoursAdd > @HoursPerDay)
BEGIN
SET @Date = @Date + 1
SET @HoursAdd = @HoursAdd - @HoursPerDay
END
ELSE
BEGIN
--add the remainder of the day
SET @Date = DATEADD(mi, (@HoursAdd + @StartOfDay) * 60, DATEDIFF(dd,0,@Date))
SET @HoursAdd = 0
END
END
END
END
RETURN @Date
END