Рассчитать секунды между двумя датами, включая рабочие часы, исключая праздничные дни, час начала 08:30 - PullRequest
0 голосов
/ 10 декабря 2018

При поиске решения для моего вопроса я нашел следующий sql ( Рассчитать рабочие часы между двумя датами ).

Однако я хочу, чтобы начальная точка была 8:30 вместо 9, а конечная точка 17:30 вместо 17. В настоящее время я использую целое число.Кто-нибудь может мне с этим помочь?Заранее спасибо!

    Create Function GetWorkingMin(@StartDate DateTime, @EndDate DateTime, @Country Varchar(2)) Returns Int 
AS
Begin
Declare @WorkMin int = 0   -- Initialize counter
Declare @Reverse bit       -- Flag to hold if direction is reverse
Declare @StartHour int = 9   -- Start of business hours (can be supplied as an argument if needed)
Declare @EndHour int = 17    -- End of business hours (can be supplied as an argument if needed)
Declare @Holidays Table (HDate DateTime)   --  Table variable to hold holidayes

-- 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 (Feel free to remove this or modify as per your DB schema)
Insert Into @Holidays (HDate) Select HDate from HOLIDAY Where COUNTRYCODE=@Country and HDATE>=DateAdd(dd, DateDiff(dd,0,@StartDate), 0)

If DatePart(HH, @StartDate)<@StartHour Set @StartDate = DateAdd(hour, @StartHour, DateDiff(DAY, 0, @StartDate))  -- If Start time is less than start hour, set it to start hour
If DatePart(HH, @StartDate)>=@EndHour+1 Set @StartDate = DateAdd(hour, @StartHour+24, DateDiff(DAY, 0, @StartDate)) -- If Start time is after end hour, set it to start hour of next day
If DatePart(HH, @EndDate)>=@EndHour+1 Set @EndDate = DateAdd(hour, @EndHour, DateDiff(DAY, 0, @EndDate)) -- If End time is after end hour, set it to end hour
If DatePart(HH, @EndDate)<@StartHour Set @EndDate = DateAdd(hour, @EndHour-24, DateDiff(DAY, 0, @EndDate)) -- If End time is before start hour, set it to end hour of previous day

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 Set @WorkMin=DATEDIFF(MI, @StartDate, @EndDate) -- Calculate difference
        Else Return 0
    Else Return 0
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, @EndHour, DateDiff(DAY, 0, @StartDate)))
                    Set @StartDate=DateAdd(hour, @StartHour+24, DateDiff(DAY, 0, @StartDate)) 
                    Set @Partial=0 
                End
                Else Begin      -- If this is a full day, add full minutes
                    Set @WorkMin=@WorkMin + (@EndHour-@StartHour)*60        
                    Set @StartDate = DATEADD(DD,1,@StartDate)
                End
            End
            Else Set (at)StartDate = DATEADD(HOUR, (at)StartHour, CAST(CAST(DATEADD(DD,1,(at)StartDate) AS DATE) AS DATETIME))  
        End
        Else Set (at)StartDate = DATEADD(HOUR, (at)StartHour, CAST(CAST(DATEADD(DD,1,(at)StartDate) AS DATE) AS DATETIME))
    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
            If @Partial=0 Set @WorkMin=@WorkMin + DATEDIFF(MI, @StartDate, @EndDate) Else Set @WorkMin=@WorkMin + DATEDIFF(MI, DateAdd(hour, @StartHour, DateDiff(DAY, 0, @StartDate)), @EndDate)
End 
If @Reverse=1 Set @WorkMin=-@WorkMin
Return @WorkMin

Конец

1 Ответ

0 голосов
/ 10 декабря 2018

Используйте TIME для времени запуска.Затем создайте переменную INT, чтобы преобразовать значение в минуту в условия.

Я создал образец для вас.

DECLARE @StartDate  DATETIME='2018-12-10 10:00'
DECLARE @ExpectedStartTime  TIME='08:30'

DECLARE @ExpectedStartMin   INT=DATEPART(HOUR,@ExpectedStartTime)*60+DATEPART(MINUTE,@ExpectedStartTime)
DECLARE @ActualStartMin     INT=DATEPART(HOUR,@StartDate)*60+DATEPART(MINUTE,@StartDate)

--Check before change the StartDate
SELECT @ExpectedStartMin, @ActualStartMin, @StartDate


If @ExpectedStartMin<@ActualStartMin Set @StartDate = CAST(CAST(@StartDate AS DATE) AS DATETIME)+@ExpectedStartTime
-- same way to the other conditions.
--
--

--Check after change the StartDate  
SELECT @ExpectedStartMin, @ActualStartMin, @StartDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...