2012-01-18 28 views
0

給定開始和結束時間,我想知道給定小時內有多少分鐘。計算給定小時內使用的分鐘數

create function CalcMinsInHour(@start datetime, @end datetime, @hour int) 
returns int 
as 
begin 
    --Looking for best way to write this part 
end 

CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 7) should return 0 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 8) should return 45 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 9) should return 60 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 10) should return 30 
CalcMinsInHour('2012-01-18 8:15', '2012-01-18 10:30', 11) should return 0 

編輯:@Start和@End代表員工時鐘進/出時間。所以是的,當他們在午夜工作時,他們可以跨越兩天,但不會超過這一點。

+2

是日期範圍保證只在同一天內? – RQDQ 2012-01-18 19:53:28

+1

最好的方法?聽起來更像是「一種方式」。 :) – bzlm 2012-01-18 19:53:39

+1

你想如何處理多天的跨度?如果你輸入「2012-01-18 8:15」和「2012-01-20-13:30」,你想得到什麼? – JNK 2012-01-18 19:53:48

回答

3

這應該做的伎倆:

ALTER FUNCTION dbo.CalcMinsInHour(@start DATETIME, @end DATETIME, @hour INTEGER) 
RETURNS INTEGER 
AS 
BEGIN 
    DECLARE @StartOfHour DATETIME 
    DECLARE @EndOfHour DATETIME 
    SELECT @StartOfHour = DATEADD(hh, @hour, CAST(CAST(@start AS DATE) AS DATETIME)) 
    IF NOT (@StartOfHour BETWEEN @start and @end) 
     SET @StartOfHour = DATEADD(hh, @hour, CAST(CAST(@end AS DATE) AS DATETIME)) 

    SELECT @EndOfHour = DATEADD(hh, 1, @StartOfHour) 

RETURN 
(
SELECT 
    CASE WHEN @EndOfHour < @start OR @StartOfHour > @end THEN 0 ELSE 
     DATEDIFF(mi, 
      CASE WHEN @StartOfHour <= @start THEN @start ELSE @StartOfHour END, 
      CASE WHEN @EndOfHour > @end THEN @end ELSE @EndOfHour END) 
    END 
) 
END 
+0

+1 - 比我的bazillion'CASE'聲明解決方案更優雅,我還沒有完成:) – JNK 2012-01-18 20:22:34

+0

如果間隔時間爲'2012-01-18 20:15' - '2012-01-19 2:30'且小時爲2,則此功能不起作用,例如 – GolfWolf 2012-01-18 20:28:48

+0

太棒了,您搖滾。如果你在達拉斯,我會買你的午餐:) – 2012-01-18 20:30:53

1

你可以使用DateDiff嗎?

select DATEDIFF(Minute, '2011-11-10 00:00:59.900', '2011-11-10 00:01:00.100')

+0

我認爲這將是一個具有多個DateDiff的案例陳述。想法是獲得一天中每小時工作的勞動小時數。 – 2012-01-18 20:08:52

1

下面是計算的總分鐘數(也可與多天)的功能:

create function CalcMinsInHour(@start datetime, @end datetime, @hour int) 
    returns int 
as 
begin 

    declare @selecterHourIntervals table (HourStart datetime, HourEnd datetime) 
    declare @currentDate datetime 

    /* start in the @start date, but the hour we want to count */ 
    set @currentDate = dateadd(hour, @hour, convert(datetime, convert(date, @start))) 

    /* for every day between @[email protected] add out hour interval */ 
    while @currentDate <= @end 
    begin 
     insert into @selecterHourIntervals values (
         @currentDate, 
         dateadd(hour, 1, @currentDate)) 

     set @currentDate = dateadd(day, 1, @currentDate) 
    end 

    declare @totalMinutes int 

    /* for every hour interval in the table, select number of minutes 
     trimmed by the @start - @end interval and sum */ 
    select @totalMinutes = sum(DailyMinutes) 
    from 
     (select 
      datediff(minute, 
      case when HourStart > @start then HourStart else @start end, 
      case when HourEnd < @end then HourEnd else @end end) as DailyMinutes 
     from @selecterHourIntervals) TrimmedIntervals 
    where DailyMinutes > 0 

    return isnull(@totalMinutes, 0) 

end 
+0

+ +1努力:) – 2012-01-18 20:34:36

+0

也就是說,我意識到這個答案可能比AdaTheDev更「正確」,但我真的想要一個沒有循環,臨時表等的解決方案,它會減慢速度......但絕對想要給你+1的努力! – 2012-01-18 20:41:29

+0

@BrandonMoore - 我知道,AdaTheDev的解決方案確實更加優雅,可以稍微調整以產生正確的結果 – GolfWolf 2012-01-18 20:45:10

相關問題