如何将 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
我的 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