【问题标题】:DateDiff to output hours and minutesDateDiff 输出小时和分钟
【发布时间】:2022-01-02 18:40:50
【问题描述】:

我的代码以小时为单位给出 TOTAL HOURS,但我试图输出类似

TotalHours 
  8:36

其中 8 代表小时部分,36 代表分钟部分,表示一个人一天在办公室工作的总小时数。

with times as (
SELECT    t1.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , t1.RecDate AS [DateVisited]
FROM  AtdRecord t1 
INNER JOIN 
      AtdRecord t2 
ON    t1.EmplID = t2.EmplID 
AND   t1.RecDate = t2.RecDate
AND   t1.RecTime < t2.RecTime
inner join 
      HrEmployee t3 
ON    t3.EmplID = t1.EmplID 
group by 
          t1.EmplID
        , t3.EmplName
        , t1.RecDate
)
SELECT    EmplID
        , EmplName
        , InTime
        , [TimeOut]
        , [DateVisited]
        , DATEDIFF(Hour,InTime, [TimeOut]) TotalHours
from times
Order By EmplID, DateVisited 

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    很简单:

    CONVERT(TIME,Date2 - Date1)
    

    例如:

    Declare @Date2 DATETIME = '2016-01-01 10:01:10.022'
    Declare @Date1 DATETIME = '2016-01-01 10:00:00.000'
    Select CONVERT(TIME,@Date2 - @Date1) as ElapsedTime
    

    产量:

    ElapsedTime
    ----------------
    00:01:10.0233333
    
    (1 row(s) affected)
    

    【讨论】:

    • 我赞成这个,因为它今天确实帮助了我。简单干净,给了我想要的东西。
    • 太棒了!这应该是正确的答案。为什么有人会做其他复杂且可能有问题的解决方案?
    • 不能直接减去Datetime2;您将收到以下错误:Operand data type datetime2 is invalid for subtract operator.
    • 如果返回的差异超过 24 小时,您将无法获得所需的输出。此方法将返回除以 24 的差值。
    • 用于获取具有相同日期的两个日期的差异小时和分钟。只想要我需要的。谢谢!
    【解决方案2】:

    试试这个查询

    select
        *,
        Days          = datediff(dd,0,DateDif),
        Hours         = datepart(hour,DateDif),
        Minutes       = datepart(minute,DateDif),
        Seconds       = datepart(second,DateDif),
        MS            = datepart(ms,DateDif)
    from
        (select
             DateDif = EndDate-StartDate,
             aa.*
         from
             (  -- Test Data
              Select
                  StartDate = convert(datetime,'20090213 02:44:37.923'),
                  EndDate   = convert(datetime,'20090715 13:24:45.837')) aa
        ) a
    

    输出

    DateDif                  StartDate                EndDate                 Days Hours Minutes Seconds MS
    -----------------------  -----------------------  ----------------------- ---- ----- ------- ------- ---
    1900-06-02 10:40:07.913  2009-02-13 02:44:37.923  2009-07-15 13:24:45.837 152  10    40      7       913
    
    (1 row(s) affected)
    

    【讨论】:

    • 谢谢先生,等待我的积分上升,以便我可以 UPVOTE 您的帖子
    • 我喜欢这个解决方案。谢谢。
    【解决方案3】:

    这样的小改动也可以做

      SELECT  EmplID
            , EmplName
            , InTime
            , [TimeOut]
            , [DateVisited]
            , CASE WHEN minpart=0 
            THEN CAST(hourpart as nvarchar(200))+':00' 
            ELSE CAST((hourpart-1) as nvarchar(200))+':'+ CAST(minpart as nvarchar(200))END as 'total time'
            FROM 
            (
            SELECT   EmplID, EmplName, InTime, [TimeOut], [DateVisited],
            DATEDIFF(Hour,InTime, [TimeOut]) as hourpart, 
            DATEDIFF(minute,InTime, [TimeOut])%60 as minpart  
            from times) source
    

    【讨论】:

    • Wowwwwwww 太棒了,太棒了,先生,爱你 :)
    • 只有一个问题,totalHours 列标题已被禁用,它说 NO COULUMN NAME :(
    • 将标题的查询更新为“总时间”
    • 和@DhruvJoshi 先生,请解释一下你做了什么,有点难以理解你的逻辑
    • @VigneshKumar:先生,哪个答案?
    【解决方案4】:

    我会让你最终选择:

    SELECT    EmplID
            , EmplName
            , InTime
            , [TimeOut]
            , [DateVisited]
            , CONVERT(varchar(3),DATEDIFF(minute,InTime, TimeOut)/60) + ':' +
              RIGHT('0' + CONVERT(varchar(2),DATEDIFF(minute,InTime,TimeOut)%60),2)
              as TotalHours
    from times
    Order By EmplID, DateVisited 
    

    任何尝试使用DATEDIFF(hour,... 的解决方案都一定会很复杂(如果它是正确的),因为DATEDIFF 计算转换-DATEDIFF(hour,...09:59',...10:01') 将返回 1,因为时间从 9 点转换到 10 点。所以我只需在几分钟内使用DATEDIFF

    如果涉及秒,上述内容仍然可能存在细微的错误(由于其计数分钟转换,它可能会略微过度计数),因此如果您需要秒或毫秒精度,则需要调整 DATEDIFF 以使用这些单位,然后应用合适的除法常量(根据上面的小时数)只返回小时和分钟。

    【讨论】:

      【解决方案5】:

      换个方式

      DATEDIFF(Hour,InTime, [TimeOut]) TotalHours
      

      部分到

      CONCAT((DATEDIFF(Minute,InTime,[TimeOut])/60),':',
             (DATEDIFF(Minute,InTime,[TimeOut])%60)) TotalHours 
      

      /60 表示小时数,%60 表示剩余分钟数,而 CONCAT 允许您在它们之间添加一个冒号。

      我知道这是一个老问题,但我遇到了它,并认为如果其他人遇到它可能会有所帮助。

      【讨论】:

        【解决方案6】:

        将MS中的Datediff除以一天中的毫秒数,转换为Datetime,然后转换为时间:

        Declare @D1 datetime = '2015-10-21 14:06:22.780', @D2 datetime = '2015-10-21 14:16:16.893'
        
        Select  Convert(time,Convert(Datetime, Datediff(ms,@d1, @d2) / 86400000.0))
        

        【讨论】:

          【解决方案7】:

          如果你想要 08:30 (HH:MM) 格式,那么试试这个,

          SELECT EmplID
              , EmplName
              , InTime
              , [TimeOut]
              , [DateVisited]
              ,  RIGHT('0' + CONVERT(varchar(3),DATEDIFF(minute,InTime, TimeOut)/60),2) + ':' +
                RIGHT('0' + CONVERT(varchar(2),DATEDIFF(minute,InTime,TimeOut)%60),2)
                as TotalHours from times Order By EmplID, DateVisited
          

          【讨论】:

            【解决方案8】:

            请输入您的相关值并尝试一下:

            declare @x int, @y varchar(200),
                    @dt1 smalldatetime = '2014-01-21 10:00:00', 
                    @dt2 smalldatetime = getdate()
            
            set @x = datediff (HOUR, @dt1, @dt2)
            set @y =  @x * 60 -  DATEDIFF(minute,@dt1, @dt2)
            set @y = cast(@x as varchar(200)) + ':' + @y
            Select @y
            

            【讨论】:

              【解决方案9】:

              [hh:mm:ss] 中的两个时间差

              select FORMAT((CONVERT(datetime,'2021-12-01 19:24:40') - CONVERT(datetime,'2021-12-01 17:00:00')),'hh:mm:ss')DffTime
              

              【讨论】:

                【解决方案10】:

                这会帮助你

                 DECLARE @DATE1 datetime = '2014-01-22 9:07:58.923'
                 DECLARE @DATE2 datetime = '2014-01-22 10:20:58.923'
                 SELECT DATEDIFF(HOUR, @DATE1,@DATE2) ,
                        DATEDIFF(MINUTE, @DATE1,@DATE2) - (DATEDIFF(HOUR,@DATE1,@DATE2)*60)
                
                 SELECT CAST(DATEDIFF(HOUR, @DATE1,@DATE2) AS nvarchar(200)) +
                        ':'+ CAST(DATEDIFF(MINUTE, @DATE1,@DATE2)  -
                                 (DATEDIFF(HOUR,@DATE1,@DATE2)*60) AS nvarchar(200))
                As TotalHours 
                

                【讨论】:

                • @Date1 设置为 '2014-01-22 9:47:58.923' 并通过您的代码观察那是 1 小时 -27 分钟。
                【解决方案11】:

                由于任何 DateTime 都可以转换为浮点数,并且数字的小数部分表示时间本身:

                DECLARE @date DATETIME = GETDATE()
                
                SELECT CAST(CAST(@date AS FLOAT) - FLOOR(CAST(@date AS FLOAT)) AS DATETIME
                

                这将产生一个日期时间,例如“一天中的 1900-01-01 小时”,您可以将其转换为时间、时间戳,甚至使用转换来获取格式化的时间。

                我猜这适用于任何版本的 SQL,因为自 2005 版以来将日期时间转换为浮点是兼容的。

                希望对你有帮助。

                【讨论】:

                  【解决方案12】:

                  如果有人仍在搜索查询以显示 hr min 和 sec 格式的差异: (这将以这种格式显示差异:2 小时 20 分 22 秒)

                  SELECT
                  CAST(DATEDIFF(minute, StartDateTime, EndDateTime)/ 60 as nvarchar(20)) + ' hrs ' + CAST(DATEDIFF(second, StartDateTime, EndDateTime)/60 as nvarchar(20)) + ' mins' +          CAST(DATEDIFF(second, StartDateTime, EndDateTime)% 60 as nvarchar(20))  + ' secs'
                  

                  OR 可以是问题中的格式:

                  CAST(DATEDIFF(minute, StartDateTime, EndDateTime)/ 60 as nvarchar(20)) + ':' + CAST(DATEDIFF(second, StartDateTime, EndDateTime)/60 as nvarchar(20))
                  

                  【讨论】:

                    【解决方案13】:

                    无需跳槽。从结束减去开始基本上给你时间跨度 (结合 Vignesh Kumar 和 Carl Nitzsche 的回答):

                    SELECT *,
                        --as a time object
                        TotalHours = CONVERT(time, EndDate - StartDate),
                        --as a formatted string
                        TotalHoursText = CONVERT(varchar(20), EndDate - StartDate, 114)
                    FROM (
                        --some test values (across days, but OP only cares about the time, not date)
                        SELECT
                            StartDate = CONVERT(datetime,'20090213 02:44:37.923'),
                            EndDate   = CONVERT(datetime,'20090715 13:24:45.837')
                    ) t
                    

                    输出

                    StartDate               EndDate                 TotalHours       TotalHoursText
                    ----------------------- ----------------------- ---------------- --------------------
                    2009-02-13 02:44:37.923 2009-07-15 13:24:45.837 10:40:07.9130000 10:40:07:913
                    

                    在此处查看完整的演员表和转换选项: https://msdn.microsoft.com/en-us/library/ms187928.aspx

                    【讨论】:

                    • 你的意思是从2月13日到7月15日只有10个小时?嗯 - 最好在发布前检查你的结果!
                    • @Teo,故意使用多天的跨度来突出这种确切的行为,并在我的代码注释中明确指出。它与当前投票率最高的答案中使用的方法相同(但出于说明目的更详细)。
                    猜你喜欢
                    • 1970-01-01
                    • 2016-11-15
                    • 1970-01-01
                    • 2016-08-31
                    • 2021-07-14
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-03-22
                    相关资源
                    最近更新 更多