Quantcast
Channel: Transact-SQL forum
Viewing all articles
Browse latest Browse all 23857

Calculate duration between start date and end date

$
0
0

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


Viewing all articles
Browse latest Browse all 23857

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>