Différence de deux date et heure dans le serveur SQL

83

Existe-t-il un moyen de faire la différence entre deux datetimeserveurs SQL?

Par exemple, mes dates sont

  1. 2010-01-22 15:29:55.090
  2. 2010-01-22 15:30:09.153

Donc, le résultat devrait être 14.063 seconds.

Jibu P C_Adoor
la source
2
Vous obtenez toutes les datediffréponses, mais aucune ne semble vous rappeler que vous pourriez en obtenir des résultats négatifs en fonction de l'ordre des paramètres.
Pasi Savolainen

Réponses:

94

Juste une mise en garde à ajouter à propos de DateDiff, il compte le nombre de fois que vous passez la limite que vous spécifiez comme vos unités, il est donc sujet à des problèmes si vous recherchez une période précise. par exemple

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

donne une réponse de 1, car il a franchi la frontière de janvier à février, donc même si la durée est de 2 jours, dateiff renverrait une valeur de 1 - il a franchi 1 limite de date.

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

Donne une valeur de 1, encore une fois, il a passé la limite des minutes une fois, donc même s'il est d'environ 14 secondes, il serait renvoyé comme une seule minute lors de l'utilisation des minutes comme unités.

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

Remplacez "MyUnits" basé sur DATEDIFF sur MSDN

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

Remplacez-les daypar d'autres unités dans lesquelles vous souhaitez obtenir la différence, comme second, minuteetc.

Quassnoi
la source
16

Je peux mentionner quatre fonctions importantes de MS SQL Server qui peuvent être très utiles:

1) La fonction DATEDIFF () est chargée de calculer les différences entre deux dates, le résultat pourrait être " année trimestre mois jour sur année jour semaine heure minute seconde milliseconde microseconde nanoseconde ", spécifié sur le premier paramètre ( datepart ):

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

2) Vous pouvez utiliser la fonction GETDATE () pour obtenir l'heure réelle et calculer les différences d'une date et d'une date réelle:

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

3) Une autre fonction importante est DATEADD () , utilisée pour convertir une valeur dans datetime en utilisant la même partie de date du datetime, que vous pouvez ajouter (avec des valeurs positives) ou soustraire (avec des valeurs négatives) à une date de base:

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

4) La fonction CONVERT () a été conçue pour formater la date comme vous en avez besoin, ce n'est pas une fonction paramétrique, mais vous pouvez utiliser une partie du résultat pour formater le résultat comme vous en avez besoin:

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 froid être calculé en secondes et un résultat intéressant mélangeant ces quatre fonctions est de montrer une différence formatée um heures, minutes et secondes ( hh: mm: ss ) entre deux dates:

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)

... le résultat est 00:10:38 (638s = 600s + 38s = 10 minutes et 38 secondes)

Un autre exemple:

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

J'ai essayé de cette façon et cela a fonctionné. J'ai utilisé la version 2016 de SQL Server

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

Les différentes fonctions DATEDIFF sont:

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');

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

rchacko
la source
7

Ok, nous savons tous que la réponse implique DATEDIFF(). Mais cela ne vous donne que la moitié du résultat recherché. Que faire si vous souhaitez obtenir les résultats dans un format lisible par l'homme, en termes de minutes et de secondes entre deux DATETIMEvaleurs?

Les fonctions CONVERT(), DATEADD()et bien sûr DATEDIFF()sont parfaites pour un résultat plus facilement lisible que vos clients peuvent utiliser, au lieu d'un nombre.

c'est à dire

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

Cela vous donnera quelque chose comme:

HH: MM

Si vous voulez plus de précision, augmentez simplement la valeur VARCHAR().

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

HH: MM.SS.MS

Fandango68
la source
5

En interne, dans SQL Server, les dates sont stockées sous forme de 2 entiers. Le premier entier est le nombre de dates avant ou après la date de base (01/01/1900). Le deuxième entier stocke le nombre de ticks d'horloge après minuit, chaque tick est de 1/300 de seconde.

Plus d'infos ici

Pour cette raison, je trouve souvent que le moyen le plus simple de comparer des dates est de simplement les soustraire. Cela gère 90% de mes cas d'utilisation. Par exemple,

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

Lorsque j'ai besoin d'une réponse en unités autres que les jours, j'utiliserai DateDiff .

RedFilter
la source
6
Notez que cela ne concerne que l'ancien DATETIMEtype de ne pas DATE, TIMEou DATETIME2. De plus, la valeur renvoyée sera une autre DATETIME, vous devrez donc la caster pour obtenir le nombre de jours lisible par l'homme entre les dates.
5

Il existe un certain nombre de façons de regarder une différence de date, et plus encore lors de la comparaison des dates / heures. Voici ce que j'utilise pour obtenir la différence entre deux dates au format "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)

Je l'ai utilisé pour une colonne calculée, mais vous pouvez la réécrire de manière triviale en tant que calcul UDF ou requête. Notez que cette logique arrondit les fractions de seconde vers le bas; 00: 00.00 à 00: 00.999 est considéré comme zéro seconde et affiché comme "00:00:00".

Si vous prévoyez que les périodes peuvent durer plus de quelques jours, ce code passe au format D: HH: MM: SS si nécessaire:

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

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

Cela vous donne la différence entre deux dates dans l' année

Ici (2017-2011) = 6 en conséquence

Syntaxe:

DATEDIFF(interval, date1, date2)
Abhishek Kanrar
la source
2

Utilisez ceci pour 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) 
user3777604
la source
1

Ce n'est donc pas ma réponse, mais je viens de trouver cela en recherchant en ligne une question comme celle-ci. Ce type a mis en place une procédure pour calculer les heures, les minutes et les secondes. Le lien et le code:

--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'
)
Jfabs
la source
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))
Kash
la source
1

IMPRIMER DATEDIFF (deuxième, '2010-01-22 15: 29: 55.090', '2010-01-22 15: 30: 09.153')

Abhishek Jaiswal
la source
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

Je pensais juste que je le mentionnerais.

Used_By_Already
la source
1

CREATE FUNCTION getDateDiffHours (@fdate AS datetime, @ tdate as datetime) RETURNS varchar (50) AS BEGIN 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'

FIN

George Hedley
la source
1
Pouvez-vous expliquer votre code en fonction de la question?
user7294900
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 fonctionne le mieux

Lalitha Poluri
la source
1

Veuillez vérifier ci-dessous l'astuce pour trouver la différence de date entre deux dates

 DATEDIFF(DAY,ordr.DocDate,RDR1.U_ProgDate) datedifff

où vous pouvez changer selon vos besoins comme vous voulez la différence de jours ou de mois ou d'année ou d'heure.

Bha15
la source
0

Pour moi, cela a fonctionné parfaitement Convertir (varchar (8), DATEADD (SECOND, DATEDIFF (SECOND, LogInTime, LogOutTime), 0), 114)

et la sortie est HH: MM: SS qui est montrée avec précision dans mon cas.

clarificateur
la source
-1

Vérifier la dateDifférent sur Books Online.

Martin Clarke
la source