sql server中两个日期时间的差异

时间:2010-01-22 10:22:56

标签: sql sql-server datetime

有没有办法在sql server中区分两个datetime

例如,我的日期是

  1. 2010-01-22 15:29:55.090
  2. 2010-01-22 15:30:09.153
  3. 因此,结果应为14.063 seconds

21 个答案:

答案 0 :(得分:83)

添加关于DateDiff的警告只是一个警告,它会计算您指定为单位的边界的次数,因此如果您要查找精确的时间跨度,则会遇到问题。 e.g。

select datediff (m, '20100131', '20100201')

给出1的答案,因为它从1月到2月越过了边界,所以即使跨度为2天,datediff也会返回值1 - 它越过1个日期边界。

select datediff(mi, '2010-01-22 15:29:55.090' , '2010-01-22 15:30:09.153')

给出一个值1,它再次超过分钟边界一次,所以即使它大约是14秒,当使用Minutes作为单位时,它将作为一分钟返回。

答案 1 :(得分:24)

SELECT DATEDIFF (MyUnits, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')

根据DATEDIFF on MSDN

替换“MyUnits”

答案 2 :(得分:12)

SELECT  DATEDIFF(day, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')

day替换为您希望获得差异的其他单位,例如secondminute等。

答案 3 :(得分:10)

我可以提到两个非常有用的MS SQL Server重要功能:

1)函数DATEDIFF()负责计算两个日期之间的差异,结果可能是" 年度季度日,每年每周工作小时第二毫秒微秒纳秒&# 34;,在第一个参数( datepart )上指定:

select datediff(day,'1997-10-07','2011-09-11')

2)您可以使用函数GETDATE()来获取实际时间并计算某些日期和实际日期的差异:

select datediff(day,'1997-10-07', getdate() )

3)另一个重要的功能是DATEADD(),用于在datetime中使用相同的 datepart 转换某些值,您可以添加(带正值)或减去(带有负值)到一个基准日期:

select DATEADD(day,  45, getdate()) -- actual datetime adding 45 days
select DATEADD(  s,-638, getdate()) -- actual datetime subtracting 10 minutes and 38 seconds

4)函数CONVERT()用于根据需要格式化日期,它不是参数函数,但您可以使用部分结果来格式化您需要的结果:

select convert(  char(8), getdate() ,   8) -- part hh:mm:ss of actual datetime
select convert(  varchar, getdate() , 112) -- yyyymmdd
select convert( char(10), getdate() ,  20) -- yyyy-mm-dd limited by 10 characters

DATETIME冷却以秒计算,混合这四个函数的一个有趣结果是显示两个日期之间的小时,分​​钟和秒( hh:mm:ss )的格式差异:

declare  @date1 datetime, @date2 datetime
set @date1=DATEADD(s,-638,getdate())
set @date2=GETDATE()

select convert(char(8),dateadd(s,datediff(s,@date1,@date2),'1900-1-1'),8)

...结果 00:10:38 (638s = 600s + 38s = 10分38秒)

另一个例子:

select distinct convert(char(8),dateadd(s,datediff(s, CRDATE , GETDATE() ),'1900-1-1'),8) from sysobjects order by 1

答案 4 :(得分:5)

SQL Server内部日期存储为2个整数。第一个整数是基准日期之前或之后的日期数(1900/01/01)。第二个整数存储午夜后的时钟滴答数,每个滴答是1/300秒。

More info here

因此,我经常发现比较日期的最简单方法就是简单地减去日期。这可以处理我90%的用例。例如,

select date1, date2, date2 - date1 as DifferenceInDays
from MyTable
...

当我需要以天为单位的答案时,我会使用DateDiff

答案 5 :(得分:5)

有许多方法可以查看日期差异,在比较日期/时间时有更多。以下是我用来区分格式为" HH:MM:SS"

的两个日期之间的区别
ElapsedTime AS
      RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate)        / 3600 AS VARCHAR(2)), 2) + ':'
    + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 /   60 AS VARCHAR(2)), 2) + ':'
    + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %   60        AS VARCHAR(2)), 2)

我将它用于计算列,但您可以将其重写为UDF或查询计算。请注意,此逻辑会向下舍入小数秒; 00:00.00至00:00.999被视为零秒,并显示为" 00:00:00"。

如果您预计这段时间可能会超过几天,则此代码会在需要时切换为D:HH:MM:SS格式:

ElapsedTime AS
    CASE WHEN DATEDIFF(S, StartDate, EndDate) >= 359999
        THEN
                          CAST(DATEDIFF(S, StartDate, EndDate) / 86400        AS VARCHAR(7)) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 86400 / 3600 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %  3600 /   60 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %    60        AS VARCHAR(2)), 2)
        ELSE
              RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate)        / 3600 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 /   60 AS VARCHAR(2)), 2) + ':'
            + RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) %   60        AS VARCHAR(2)), 2)
        END

答案 6 :(得分:5)

我尝试过这种方法,并且有效。我使用SQL Server 2016版

SELECT DATEDIFF(MILLISECOND,'2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')/1000.00;

不同的DATEDIFF函数是:

SELECT DATEDIFF(year,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter,     '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month,       '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear,   '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day,         '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour,        '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute,      '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second,      '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');

参考:https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-2017

答案 7 :(得分:4)

以下查询应该提供您正在寻找的确切内容。

false

以下是来自MSDN的链接,您可以使用datediff函数执行所有操作。 https://msdn.microsoft.com/en-us/library/ms189794.aspx

答案 8 :(得分:2)

好吧,我们都知道答案涉及DATEDIFF()。但这只会给您带来一半的结果。如果要以两个DATETIME值之间的分钟和秒为单位,以人类可读的格式获取结果,怎么办?

CONVERT()DATEADD(),当然还有DATEDIFF()函数对于获得更易于阅读的结果(而不是数字)的客户而言是完美的。

CONVERT(varchar(5), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114) 

这将为您提供以下信息:

  

HH:MM

如果要提高精度,只需增加VARCHAR()

CONVERT(varchar(12), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114) 
  

HH:MM.SS.MS

答案 9 :(得分:1)

在联机丛书上查看DateDiff。

答案 10 :(得分:1)

SELECT DATEDIFF(yyyy, '2011/08/25', '2017/08/25') AS DateDiff

它为您提供

中两个日期之间的时差

结果(2017-2011)= 6

语法:

DATEDIFF(interval, date1, date2)

答案 11 :(得分:1)

请查看以下技巧以查找两个日期之间的日期差异

{{1}}

您可以根据需要更改日期,月份或年份或时间的差异。

答案 12 :(得分:1)

Sol-1:

select 
  StartTime
  , EndTime
  , CONVERT(NVARCHAR,(EndTime-StartTime), 108) as TimeDiff 
from 
  [YourTable]

Sol-2:

select 
  StartTime
  , EndTime
  , DATEDIFF(hh, StartTime, EndTime)
  , DATEDIFF(mi, StartTime, EndTime) % 60 
from 
  [YourTable]

Sol-3:

select 
  DATEPART(hour,[EndTime]-[StartTime])
  , DATEPART(minute,[EndTime]-[StartTime]) 
from 
  [YourTable]

Datepart工作得最好

答案 13 :(得分:1)

CREATE FUNCTION getDateDiffHours(@fdate AS datetime,@ tdate as datetime) 退货varchar(50) 如 开始     DECLARE @cnt int     DECLARE @cntDate datetime     DECLARE @dayDiff int     DECLARE @dayDiffWk int     DECLARE @hrsDiff decimal(18)

DECLARE @markerFDate datetime
DECLARE @markerTDate datetime

DECLARE @fTime int
DECLARE @tTime int 


DECLARE @nfTime varchar(8)
DECLARE @ntTime varchar(8)

DECLARE @nfdate datetime
DECLARE @ntdate datetime

-------------------------------------
--DECLARE @fdate datetime
--DECLARE @tdate datetime

--SET @fdate = '2005-04-18 00:00:00.000'
--SET @tdate = '2005-08-26 15:06:07.030'
-------------------------------------

DECLARE @tempdate datetime

--setting weekends
SET @fdate = dbo.getVDate(@fdate)
SET @tdate = dbo.getVDate(@tdate)
--RETURN @fdate 

SET @fTime = datepart(hh,@fdate)
SET @tTime = datepart(hh,@tdate)
--RETURN @fTime 
if datediff(hour,@fdate, @tdate) <= 9

        RETURN(convert(varchar(50),0) + ' Days ' + convert(varchar(50),datediff(hour,@fdate, @tdate)))  + ' Hours'
else
--setting working hours
SET @nfTime = dbo.getV00(convert(varchar(2),datepart(hh,@fdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@fdate))) + ':'+  dbo.getV00(convert(varchar(2),datepart(ss,@fdate)))
SET @ntTime = dbo.getV00(convert(varchar(2),datepart(hh,@tdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@tdate))) + ':'+  dbo.getV00(convert(varchar(2),datepart(ss,@tdate)))

IF @fTime > 17 
begin
    set @nfTime = '17:00:00'
end 
else
begin
    IF @fTime < 8 
        set @nfTime = '08:00:00'
end 

IF @tTime > 17 
begin
    set @ntTime = '17:00:00'
end 
else
begin
    IF @tTime < 8 
        set @ntTime = '08:00:00'
end 



-- used for working out whole days

SET @nfdate = dateadd(day,1,@fdate) 

SET @ntdate = @tdate
SET @nfdate = convert(varchar,datepart(yyyy,@nfdate)) + '-' + convert(varchar,datepart(mm,@nfdate)) + '-' + convert(varchar,datepart(dd,@nfdate))
SET @ntdate = convert(varchar,datepart(yyyy,@ntdate)) + '-' + convert(varchar,datepart(mm,@ntdate)) + '-' + convert(varchar,datepart(dd,@ntdate))
SET @cnt = 0
SET @dayDiff = 0 
SET @cntDate = @nfdate
SET @dayDiffWk = convert(decimal(18,2),@ntdate-@nfdate)

--select @nfdate,@ntdate

WHILE @cnt < @dayDiffWk
BEGIN   
    IF (NOT DATENAME(dw, @cntDate) = 'Saturday') AND (NOT DATENAME(dw, @cntDate) = 'Sunday')
    BEGIN 
        SET @dayDiff = @dayDiff + 1
    END 
    SET @cntDate = dateadd(day,1,@cntDate)
    SET @cnt = @cnt + 1
END 

--SET @dayDiff = convert(decimal(18,2),@ntdate-@nfdate) --datediff(day,@nfdate,@ntdate)
--SELECT @dayDiff

set @fdate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + @nfTime
set @tdate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + @ntTime

set @markerFDate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + '17:00:00'
set @markerTDate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + '08:00:00'

--select @fdate,@tdate
--select @markerFDate,@markerTDate

set @hrsDiff = convert(decimal(18,2),datediff(hh,@fdate,@markerFDate))

--select @hrsDiff
set @hrsDiff = @hrsDiff +  convert(int,datediff(hh,@markerTDate,@tdate))

--select @fdate,@tdate  

IF convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate))  
BEGIN
    --SET @hrsDiff = @hrsDiff - 9
    Set @hrsdiff = datediff(hour,@fdate,@tdate)
END 

--select FLOOR((@hrsDiff / 9))

IF (@hrsDiff / 9) > 0 
BEGIN
    SET @dayDiff = @dayDiff + FLOOR(@hrsDiff / 9)
    SET @hrsDiff = @hrsDiff - FLOOR(@hrsDiff / 9)*9
END 

--select convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff)   + ' Hours'

RETURN(convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff))    + ' Hours'

END

答案 14 :(得分:1)

select
datediff(millisecond,'2010-01-22 15:29:55.090','2010-01-22 15:30:09.153') / 1000.0 as Secs

result:
Secs
14.063

想到我提到它。

答案 15 :(得分:1)

PRINT DATEDIFF(第二,'2010-01-22 15:29:55.090','2010-01-22 15:30:09.153')

答案 16 :(得分:1)

declare @dt1 datetime='2012/06/13 08:11:12', @dt2 datetime='2012/06/12 02:11:12'

select CAST((@dt2-@dt1) as time(0))

答案 17 :(得分:1)

所以这不是我的答案,但我在网上搜索这样的问题时发现了这个问题。这家伙设置了一个计算小时,分钟和秒的程序。 link和代码:

--Creating Function
If OBJECT_ID('UFN_HourMinuteSecond') Is Not Null
Drop Function dbo.UFN_HourMinuteSecond
Go
Exec(
'Create Function dbo.UFN_HourMinuteSecond
(
@StartDateTime DateTime,
@EndDateTime DateTime
) Returns Varchar(10) 
As
Begin

Declare @Seconds Int,
@Minute Int,
@Hour Int,
@Elapsed Varchar(10)

Select @Seconds = ABS(DateDiff(SECOND ,@StartDateTime,@EndDateTime))

If @Seconds >= 60 
Begin
select @Minute = @Seconds/60
select @Seconds = @Seconds%60

If @Minute >= 60
begin
select @hour = @Minute/60
select @Minute = @Minute%60
end

Else
Goto Final 
End

Final:
Select @Hour = Isnull(@Hour,0), @Minute = IsNull(@Minute,0), @Seconds =               IsNull(@Seconds,0)
select @Elapsed = Cast(@Hour as Varchar) + '':'' + Cast(@Minute as Varchar) + '':'' +     Cast(@Seconds as Varchar)

Return (@Elapsed)
End'
)

答案 18 :(得分:0)

对我来说,这很完美 Convert(varchar(8),DATEADD(SECOND,DATEDIFF(SECOND,LogInTime,LogOutTime),0),114)

,输出为 HH:MM:SS在我的情况下可以正确显示。

答案 19 :(得分:0)

将此用于DD:MM:SS

SELECT CONVERT(VARCHAR(max), Datediff(dd, '2019-08-14 03:16:51.360', 
         '2019-08-15 05:45:37.610')) 
       + ':' 
       + CONVERT(CHAR(8), Dateadd(s, Datediff(s, '2019-08-14 03:16:51.360', 
         '2019-08-15 05:45:37.610'), '1900-1-1'), 8) 

答案 20 :(得分:0)

请试试

DECLARE @articleDT DATETIME;
DECLARE @nowDate DATETIME;
 
-- Time of the ARTICLE created
SET @articleDT = '2012-04-01 08:10:16';
 
-- Simulation of NOW datetime
-- (in real world you would probably use GETDATE())
SET @nowDate = '2012-04-10 11:35:36';
 
-- Created 9 days ago.
SELECT 'Created ' + CAST(DATEDIFF(day, @articleDT, @nowDate) AS NVARCHAR(50)) + ' days ago.';
 
-- Created 1 weeks, 2 days, 3 hours, 25 minutes and 20 seconds ago.
SELECT 'Created '
    + CAST(DATEDIFF(second, @articleDT, @nowDate) / 60 / 60 / 24 / 7 AS NVARCHAR(50)) + ' weeks, '
    + CAST(DATEDIFF(second, @articleDT, @nowDate) / 60 / 60 / 24 % 7 AS NVARCHAR(50)) + ' days, '
    + CAST(DATEDIFF(second, @articleDT, @nowDate) / 60 / 60 % 24  AS NVARCHAR(50)) + ' hours, '
    + CAST(DATEDIFF(second, @articleDT, @nowDate) / 60 % 60 AS NVARCHAR(50)) + ' minutes and '
    + CAST(DATEDIFF(second, @articleDT, @nowDate) % 60 AS NVARCHAR(50)) + ' seconds ago.';