Diferencia de dos fechas y horas en SQL Server


83

¿Hay alguna forma de tomar la diferencia entre dos datetimeen el servidor SQL?

Por ejemplo, mis fechas son

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

Entonces, el resultado debería ser 14.063 seconds.


2
Está obteniendo todas las datediffrespuestas, pero ninguna parece recordarle que puede obtener resultados negativos dependiendo del orden de los parámetros.
Pasi Savolainen

Respuestas:


94

Solo una advertencia para agregar sobre DateDiff, cuenta la cantidad de veces que pasa el límite que especifica como sus unidades, por lo que está sujeto a problemas si está buscando un período de tiempo preciso. p.ej

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

da una respuesta de 1, porque cruzó el límite de enero a febrero, por lo que aunque el intervalo es de 2 días, dateiff devolvería un valor de 1: cruzó el límite de 1 fecha.

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

Da un valor de 1, nuevamente, pasó el límite de los minutos una vez, por lo que aunque son aproximadamente 14 segundos, se devolvería como un solo minuto cuando se usan los minutos como unidades.


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

Sustituir "MyUnits" según DATEDIFF en MSDN


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

Reemplace daycon otras unidades en las que desee obtener la diferencia, como second, minuteetc.


16

Puedo mencionar cuatro funciones importantes de MS SQL Server que pueden ser muy útiles:

1) La función DATEDIFF () es responsable de calcular las diferencias entre dos fechas, el resultado podría ser " año cuarto mes día del año día semana hora minuto segundo milisegundo microsegundo nanosegundo ", especificado en el primer parámetro ( datepart ):

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

2) Puede usar la función GETDATE () para obtener la hora real y calcular las diferencias de algunas fechas y fechas reales:

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

3) Otra función importante es DATEADD () , que se utiliza para convertir algún valor en la fecha y hora utilizando la misma parte de la fecha del dateiff, que puede sumar (con valores positivos) o restar (con valores negativos) a una fecha 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 función CONVERT () se hizo para formatear la fecha como lo necesita, no es una función paramétrica, pero puede usar parte del resultado para formatear el resultado como lo necesita:

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 cold se calcula en segundos y un resultado interesante al mezclar estas cuatro funciones es mostrar una diferencia formateada um horas, minutos y segundos ( hh: mm: ss ) entre dos fechas:

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)

... el resultado es 00:10:38 (638s = 600s + 38s = 10 minutos y 38 segundos)

Otro ejemplo:

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

9

Intenté de esta manera y funcionó. Usé SQL Server versión 2016

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

Las diferentes funciones DATEDIFF son:

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

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


7

Ok, todos sabemos que la respuesta involucra DATEDIFF(). Pero eso le da solo la mitad del resultado que puede estar buscando. ¿Qué sucede si desea obtener los resultados en formato legible por humanos, en términos de minutos y segundos entre dos DATETIMEvalores?

Las funciones CONVERT(), DATEADD()y , por supuesto DATEDIFF(), son perfectas para un resultado más fácil de leer que sus clientes pueden usar, en lugar de un número.

es decir

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

Esto te dará algo como:

HH: MM

Si desea más precisión, simplemente aumente el VARCHAR().

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

HH: MM.SS.MS


5

Internamente, en SQL Server, las fechas se almacenan como 2 enteros. El primer entero es el número de fechas antes o después de la fecha base (1900/01/01). El segundo entero almacena el número de tics del reloj después de la medianoche, cada tick es 1/300 de segundo.

Más info aquí

Debido a esto, a menudo encuentro que la forma más sencilla de comparar fechas es simplemente restarlas. Esto maneja el 90% de mis casos de uso. P.ej,

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

Cuando necesite una respuesta en unidades que no sean días, usaré DateDiff .


6
Tenga en cuenta que esto sólo se aplica al viejo DATETIMEtipo, no DATE, TIMEo DATETIME2. Además, el valor devuelto será otro DATETIME, por lo que deberá convertirlo para obtener el número de días entre fechas legible por humanos.

5

Hay varias formas de ver una diferencia de fecha y más cuando se comparan fechas / horas. Esto es lo que uso para obtener la diferencia entre dos fechas formateadas como "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)

Usé esto para una columna calculada, pero podría reescribirlo trivialmente como un cálculo de consulta o UDF. Tenga en cuenta que esta lógica redondea fracciones de segundo; 00: 00.00 a 00: 00.999 se considera cero segundos y se muestra como "00:00:00".

Si prevé que los períodos pueden durar más de unos pocos días, este código cambia al formato D: HH: MM: SS cuando sea necesario:

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


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

Te da la diferencia entre dos fechas en el año

Aquí (2017-2011) = 6 como resultado

Sintaxis:

DATEDIFF(interval, date1, date2)

2

Use esto para 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) 

1

Entonces, esta no es mi respuesta, pero encontré esto mientras buscaba en línea una pregunta como esta también. Este tipo estableció un procedimiento para calcular horas, minutos y segundos. El enlace y el código:

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

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


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

Solo pensé en mencionarlo.


1

CREAR FUNCIÓN getDateDiffHours (@fdate AS datetime, @ tdate como datetime) DEVUELVE 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


1
¿Puede explicar su código de acuerdo con la pregunta?
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 funciona mejor


1

Consulte el siguiente truco para encontrar la diferencia de fecha entre dos fechas

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

donde puede cambiar según su requerimiento como desee la diferencia de días o mes o año o tiempo.


0

Para mí, esto funcionó perfectamente Convertir (varchar (8), DATEADD (SEGUNDO, DATEDIFF (SEGUNDO, LogInTime, LogOutTime), 0), 114)

y la salida es HH: MM: SS que se muestra con precisión en mi caso.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.