Hi everyone,
I'm facing with problem when calculating duration between start & end with this function below . This fuction is working well, but i want to change working time from 8:00 am to 17:30 pm instead of 17:00 , and lunch time from 12:00 to 13:30 instead of 13:00 as present . Problem is , i changed data type of start hour and end hour from INT to decimal . But it is still wrong .
Pls help me . It's very urgent bcoz i need it for monthly report .
Many thanks .
Here is function which im using :
ALTER Function [dbo].[GetWorkingMin](@pStartDate DateTime, @pEndDate DateTime) Returns Int
AS
Begin
Declare @StartDate DateTime = @pStartDate
Declare @EndDate DateTime = @pEndDate
Declare @WorkMin int = 0 -- Initialize counter
Declare @Reverse bit -- Flag to hold if direction is reverse
Declare @StartWorkingHour int = 8 -- Start of business hours (can be supplied as an argument if needed)
Declare @EndWorkingHour int = 17 -- End of business hours (can be supplied as an argument if needed)
Declare @Holidays Table (HDate DateTime) -- Table variable to hold holidayes
Declare @LunchHour int = 12
--
Declare @StartHour int = DatePart(HH, @StartDate)
Declare @EndHour int = DatePart(HH, @EndDate)
-- If dates are in reverse order, switch them and set flag
If @StartDate>@EndDate
Begin
Declare @TempDate DateTime=@StartDate
Set @StartDate=@EndDate
Set @EndDate=@TempDate
Set @Reverse=1
End
Else Set @Reverse = 0
-- Get country holidays from table based on the country code
Insert Into @Holidays (HDate) Select HDate from HOLIDAY Where HDATE>=DateAdd(dd, DateDiff(dd,0,@StartDate), 0)
If DatePart(HH, @StartDate)<@StartWorkingHour
begin
Set @StartDate = DateAdd(hour, @StartWorkingHour, DateDiff(DAY, 0, @StartDate))
-- If Start time is less than start hour, set it to start hour
Set @StartHour = DatePart(HH, @StartDate)
end
If DatePart(HH, @StartDate)>=@EndWorkingHour
begin
Set @StartDate = DateAdd(hour, @StartWorkingHour+24, DateDiff(DAY, 0, @StartDate))
-- If Start time is after end hour, set it to start hour of next day
Set @StartHour = DatePart(HH, @StartDate)
--return DatePart(day, @StartDate)
end
If DatePart(HH, @EndDate)>=@EndWorkingHour
begin
Set @EndDate = DateAdd(hour, @EndWorkingHour, DateDiff(DAY, 0, @EndDate))
-- If End time is after end hour, set it to end hour
Set @EndHour = DatePart(HH, @EndDate)
end
If DatePart(HH, @EndDate)<@StartWorkingHour
begin
Set @EndDate = DateAdd(hour, @EndWorkingHour-24, DateDiff(DAY, 0, @EndDate))
-- If End time is before start hour, set it to end hour of previous day
Set @EndHour = DatePart(HH, @EndDate)
end
If (@StartHour>=@LunchHour and @StartHour < (@LunchHour +1))
Begin
Set @StartDate = DateAdd(hour, @LunchHour + 1, DateDiff(DAY, 0, @StartDate))
-- If Start time is in lunch time, set it to 12
Set @StartHour = @LunchHour + 1
End
If (@StartHour>=@LunchHour and DatePart(DW, @StartDate) = 7)
Begin
Set @StartDate = DateAdd(hour, @StartWorkingHour + 24, DateDiff(DAY, 0, @StartDate))
Set @StartHour = DatePart(HH, @StartDate)
End
If (@EndHour>=@LunchHour and @EndHour < (@LunchHour +1))
Begin
Set @EndDate = DateAdd(hour, @LunchHour +1, DateDiff(DAY, 0, @EndDate))
-- If End time is in lunch time, set it to 13
Set @EndHour = @LunchHour + 1
End
If (DatePart(DW, @EndDate) = 7 and DatePart(HH, @EndDate) >= @LunchHour) Set @EndDate = DateAdd(hour, @LunchHour, DateDiff(DAY, 0, @EndDate)) -- If End day is Saturday and End time is after end hour, set it to end hour of saturday
If @StartDate>@EndDate Return 0
-- If Start and End is on same day
If DateDiff(Day,@StartDate,@EndDate) <= 0
Begin
If (Datepart(dw,@StartDate)>1 And DATEPART(dw,@StartDate)<7)
-- If day is between sunday and saturday
If (Select Count(*) From @Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,@StartDate), 0)) = 0
-- If day is not a holiday
If @EndDate<@StartDate Return 0 Else
Begin
Set @WorkMin=DATEDIFF(MI, @StartDate, @EndDate)
-- Calculate difference
If (@StartHour <= @LunchHour and @EndHour >= @LunchHour + 1)
Set @WorkMin = @WorkMin - 60;
End
Else Return 0
Else Begin
if (DATEPART(dw,@StartDate)=7) set @WorkMin = @WorkMin + DATEDIFF(MI, @StartDate, @EndDate);
Return @WorkMin
End
End
Else Begin
Declare @Partial int=1
-- Set partial day flag
While DateDiff(Day,@StartDate,@EndDate) > 0
-- While start and end days are different
Begin
If Datepart(dw,@StartDate)>1 And DATEPART(dw,@StartDate)<7 -- If this is a weekday
Begin
If (Select Count(*) From @Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,@StartDate), 0)) = 0 -- If this is not a holiday
Begin
If @Partial=1
-- If this is the first iteration, calculate partial time
Begin
Set @WorkMin=@WorkMin + DATEDIFF(MI, @StartDate, DateAdd(hour, @EndWorkingHour, DateDiff(DAY, 0, @StartDate)))
If (@StartHour <= @LunchHour) Set @WorkMin = @WorkMin - 60;
Set @StartDate=DateAdd(hour, @StartWorkingHour+24, DateDiff(DAY, 0, @StartDate))
Set @Partial=0
End
Else Begin
-- If this is a full day, add full minutes
Set @WorkMin=@WorkMin + (@EndWorkingHour-@StartWorkingHour - 1)*60
Set @StartDate = DATEADD(DD,1,@StartDate)
End
End
Else Set @StartDate = DATEADD(DD,1,@StartDate)
End
Else Begin
If (DATEPART(dw,@StartDate)=7)
Begin
Set @WorkMin = @WorkMin + DATEDIFF(MI, @StartDate, DateAdd(hour, @LunchHour, DateDiff(DAY,
0, @StartDate)));
End
--Set @StartDate = DATEADD(DD,1,@StartDate)
Set @StartDate = DateAdd(hour, @StartWorkingHour + 24, DateDiff(DAY, 0, @StartDate))
Set @StartHour = DatePart(HH, @StartDate)
End
End
If Datepart(dw,@StartDate)>1 And DATEPART(dw,@StartDate)<7
-- If last day is a weekday
If (Select Count(*) From @Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,@StartDate), 0)) = 0
-- And it is not a holiday
Begin
If @Partial=0 Set @WorkMin=@WorkMin + DATEDIFF(MI, @StartDate, @EndDate) Else
Set @WorkMin=@WorkMin + DATEDIFF(MI, DateAdd(hour, @StartWorkingHour, DateDiff(DAY, 0, @StartDate)), @EndDate)
If (@EndHour >= (@LunchHour + 1)) Set @WorkMin = @WorkMin - 60;
End
If (DATEPART(dw,@EndDate)=7)
Begin
Set @WorkMin = @WorkMin + DATEDIFF(MI, DateAdd(hour, @StartWorkingHour, DateDiff(DAY, 0, @EndDate)),@EndDate);
End
End
If @Reverse=1 Set @WorkMin=-@WorkMin
Return @WorkMin
End