¿Cómo calcular la diferencia en horas (decimal) entre dos fechas en SQL Server?

84

Tengo que calcular la diferencia en horas (tipo decimal) entre dos fechas en SQL Server 2008.

No pude encontrar ninguna técnica útil para convertir la fecha y la hora a decimal con 'CONVERT' en MSDN.
¿Alguien me puede ayudar con eso?

ACTUALIZACIÓN:
Para ser claros, también necesito la parte fraccionaria (por lo tanto, tipo decimal). Así que de 9:00 a 10:30 debería devolverme 1.5.

Bagazo
fuente

Respuestas:

162

DATEDIFF(hour, start_date, end_date)le dará el número de límites de horas cruzados entre start_dateyend_date .

Si necesita la cantidad de horas fraccionarias, puede usar DATEDIFFuna resolución más alta y dividir el resultado:

DATEDIFF(second, start_date, end_date) / 3600.0

La documentación de DATEDIFFestá disponible en MSDN:

http://msdn.microsoft.com/en-us/library/ms189794%28SQL.105%29.aspx

Phil Ross
fuente
Gran idea. Por cierto, las mismas funciones también existen en .Net, por lo que esto es útil en VB.Net o C #.
Jeff
1
¿Por qué no DATEDIFF (MINUTE, start_date, end_date) / 60.0
irfandar
8
@irfandar El datepartpasado a DATEDIFFcontrolará la resolución de la salida. Por ejemplo, si start_datey end_datedifiere en 59 segundos, DATEDIFF(MINUTE, start_date, end_date) / 60.0devolvería 0, pero DATEDIFF(second, start_date, end_date) / 3600.0devolvería 0,0163888 (59/3600).
Phil Ross
esta solución solo devuelve el número entero. si la diferencia de tiempo es de sólo 15 minutos, la hora vuelve a 0. Creo que la siguiente solución es más realista.
Asad Naeem
1
@AsadNaeem La solución (usando DATEDIFFuna resolución superior a una hora) funciona. Por ejemplo, SELECT DATEDIFF(second, DATEADD(minute, -15, GETUTCDATE()), GETUTCDATE()) / 3600.0devuelve 0,250000.
Phil Ross
15

Simplemente reste los dos valores de fecha y hora y multiplíquelos por 24:

  Select Cast((@DateTime2 - @DateTime1) as Float) * 24.0

un script de prueba podría ser:

  Declare @Dt1 dateTime Set @Dt1 = '12 Jan 2009 11:34:12'
  Declare @Dt2 dateTime Set @Dt2 = getdate()

  Select Cast((@Dt2 - @Dt1) as Float) * 24.0

Esto funciona porque todas las fechas y horas se almacenan internamente como un par de números enteros, el primer número entero es el número de días desde el 1 de enero de 1900 y el segundo número entero (que representa el tiempo) es el número de ( 1 ) tics desde la medianoche. (Para SmallDatetimes, el entero de la porción de tiempo es el número de minutos desde la medianoche). Cualquier aritmética realizada con los valores usa la porción de tiempo como una fracción de un día. 6 am = 0.25, mediodía = 0.5, etc ... Vea el enlace de MSDN aquí para obtener más detalles.

Entonces Cast ((@ Dt2 - @ Dt1) as Float) le da el total de días entre dos fechas. Multiplica por 24 para convertir a horas. Si necesita minutos totales, múltiples por minutos por día (24 * 60 = 1440) en lugar de 24 ...

NOTA 1 : Esto no es lo mismo que una marca de dotNet o javaScript; esta marca es de aproximadamente 3,33 milisegundos.

Charles Bretana
fuente
Buen truco. SQL debe incluir una constante con nombre. Me sentí sucio al escribir 24, pero supongo que eso es lo que me pasa por no ser Ronald McDonald.
Allen
10

DATEDIFF pero tenga en cuenta que devuelve un número entero, por lo que si necesita fracciones de horas, use algo como esto:

CAST(DATEDIFF(ss, startDate, endDate) AS decimal(precision, scale)) / 3600
AnthonyWJones
fuente
2

Usando Postgres tuve problemas con DATEDIFF, pero tuve éxito con esto:

  DATE_PART('day',(delivery_time)::timestamp - (placed_time)::timestamp) * 24 + 
  DATE_PART('hour',(delivery_time)::timestamp - (placed_time)::timestamp) +
  DATE_PART('minute',(delivery_time)::timestamp - (placed_time)::timestamp) / 60

que me dio una salida como "14.3"

Patrick Kearns
fuente
0
Declare @date1 datetime
Declare @date2 datetime

Set @date1 = '11/20/2009 11:00:00 AM'
Set @date2 = '11/20/2009 12:00:00 PM'

Select Cast(DateDiff(hh, @date1, @date2) as decimal(3,2)) as HoursApart

Resultado = 1,00

Ta01
fuente
1
DateDiff () devuelve un int. Podrías convertirlo a decimal, pero ya está truncado la mantisa.
Joel Coehoorn
0

Probablemente esté buscando la función DATEDIFF .

DATEDIFF (datepart, startdate, enddate)

Donde su código podría verse así:

DATEDIFF (hh, fecha de inicio, fecha de finalización)

Vincent Ramdhanie
fuente
1
El intervalo 'hh' no hará lo que él quiere. Necesita un intervalo más pequeño para poder calcular fracciones de horas.
Joel Coehoorn
0
DATEDIFF(minute,startdate,enddate)/60.0)

O use esto para 2 lugares decimales:

CAST(DATEDIFF(minute,startdate,enddate)/60.0 as decimal(18,2))
mente
fuente
-1

SELECCIONE DATEDIFF (hh, firstDate, secondDate) FROM tableName DONDE ...

LorettoDave
fuente
DateDiff () devuelve un int. Podrías convertirlo a decimal, pero ya está truncado la mantisa.
Joel Coehoorn