如何将 int 转换为时间(例如“1930”到“19:30”)并以小时和分钟 (HH:MM) 获取开始时间和结束时间之间的差异?

How to convert int to time (e.g. "1930" to "19:30") and get difference between start and end time in hours and minutes (HH:MM)?

我的 table 上有 2 列包含进出时间。我需要减去它们并得到花费的时间,甚至将它们转换为时间或任何其他方式。

CREATE TABLE [dbo].[FELData](
    [RCIN1] [numeric](4, 0) NOT NULL,
    [RCOUT1] [numeric](4, 0) NOT NULL
) ON [PRIMARY]

RCIN1        RCOUT1     Desire Result
150          1930       17:40
615          1747       11:32
410          1830       14:20
400          1600       12:00

这是我到目前为止所做的,但没有返回正确的数字

SELECT rcin1, rcout1, DATEDIFF(mi,
    CAST(STUFF(RIGHT('0'+CAST(rcin1 AS VARCHAR(8)),4),3,0,':') AS DATETIME),
    CAST(STUFF(RIGHT('0'+CAST(rcout1 AS VARCHAR(8)),4),3,0,':') AS DATETIME)
    )/60.0 AS [Hours]   
FROM FELData;

RCIN1        RCOUT1     Returning
150          1930       17.66
615          1747       11.53
410          1830       13.25
400          1600       12.83

我该如何解决这个问题?

更新

有时可能会出现用户数据输入错误,例如

RCIN1        RCOUT1     Returning
49          1930        Should return 0

谢谢

您的第一个问题是将时间存储为数字, 但这是我将数字转换为时间数据类型的方法:

declare @timeNumb int = 1500

    select 
        convert( time , (
reverse( substring( reverse( convert( varchar, @timeNumb) ) , 3, 2 ) ) + ':' +
reverse( substring( reverse( convert( varchar, @timeNumb) ) , 1, 2 ) )
                        ) 
                )

之后使用 datediff() 应该会给出您正在寻找的间隔长度。

试试这个

-- temp table for data sample
DECLARE @FELData AS TABLE
    (
      [RCIN1] NUMERIC(4, 0) ,
      [RCOUT1] NUMERIC(4, 0)
    )
INSERT  INTO @FELData
        ( RCIN1, RCOUT1 )
VALUES  ( 150, 1930 ),
        ( 615, 1747 ),
        ( 410, 1830 ),
        ( 400, 1600 )

--Solution
SELECT  T.[RCIN1] ,
        T.[RCOUT1] ,
        RIGHT('0' + CONVERT(VARCHAR(2), T.M / 60), 2) + ':'
        + RIGHT('00' + CONVERT(VARCHAR(2), T.M % 60), 2) AS Duration
FROM    ( SELECT    FD.* ,
                    DATEDIFF(MINUTE,
                             CONVERT(TIME, STUFF(RIGHT('0'
                                                       + CONVERT(VARCHAR(8), FD.[RCIN1]),
                                                       4), 3, 0, ':')),
                             CONVERT(TIME, STUFF(RIGHT('0'
                                                       + CONVERT(VARCHAR(8), FD.[RCOUT1]),
                                                       4), 3, 0, ':'))) AS M
          FROM      @FELData AS FD
        ) T 

输出结果

这几乎可以满足您的要求,但无法识别 49, 1930 是 错误的 数据。你怎么知道的?

由于您拥有的数据是数字,因此无需将其转换为散文、拆分、解析、转换、重组……。算算吧!

[更新代码]

-- Sample data.
declare @Samples as Table ( RCIn1 Numeric(4,0), RCOut1 Numeric(4,0) );
insert into @Samples ( RCIn1, RCOut1 ) values
  ( 150, 1930 ), ( 615, 1747 ),  ( 410, 1830 ), ( 400, 1600 ),
  ( 49, 1930 ); -- This is allegedly "bad" data, but no explanation is given.
select * from @Samples;

with
  -- Numeric values converted to instances of TIME datatype.
  Times as (
    select RCIn1, RCOut1,
      Cast( DateAdd( minute, Floor( RCIn1 / 100 ) * 60 + RCIn1 % 100, 0 ) as Time ) as RCIn1Time,
      Cast( DateAdd( minute, Floor( RCOut1 / 100 ) * 60 + RCOut1 % 100, 0 ) as Time ) as RCOut1Time
    from @Samples )
  -- Calculate delta times.
  select *, Cast( DateAdd( minute, DateDiff( minute, RCIn1Time, RCOut1Time ), 0 ) as Time ) as DeltaTime
    from Times