2012-01-18 136 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

相关问题