Come calcolare la differenza in ore (decimali) tra due date in SQL Server?


84

Devo calcolare la differenza in ore (tipo decimale) tra due date in SQL Server 2008.

Non sono riuscito a trovare alcuna tecnica utile per convertire datetime in decimale con "CONVERT" su MSDN.
Qualcuno può aiutarmi con quello?

AGGIORNAMENTO:
Per essere chiari, ho bisogno anche della parte frazionaria (quindi del tipo decimale). Quindi dalle 9:00 alle 10:30 dovrebbe restituirmi 1.5.

Risposte:


165

DATEDIFF(hour, start_date, end_date)ti darà il numero di limiti di ore attraversati tra start_datee end_date.

Se hai bisogno del numero di ore frazionarie, puoi usarlo DATEDIFFa una risoluzione maggiore e dividere il risultato:

DATEDIFF(second, start_date, end_date) / 3600.0

La documentazione per DATEDIFFè disponibile su MSDN:

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


Grande idea. BTW - le stesse funzioni esistono anche in .Net, quindi questo è utile in VB.Net o C #.
Jeff,

1
Perché non DATEDIFF (MINUTE, start_date, end_date) / 60.0
irfandar

8
@irfandar Il datepartpassato a DATEDIFFcontrollerà la risoluzione dell'output. Ad esempio, se start_datee end_datedifferiva di 59 secondi, DATEDIFF(MINUTE, start_date, end_date) / 60.0restituirebbe 0, ma DATEDIFF(second, start_date, end_date) / 3600.0restituirebbe 0,0163888 (59/3600).
Phil Ross

questa soluzione restituisce solo il numero intero. se la differenza di orario è di soli 15 minuti, l'ora restituisce 0. Penso che la seguente soluzione sia più realistica.
Asad Naeem

1
@AsadNaeem La soluzione (utilizzando DATEDIFFuna risoluzione maggiore di ora) funziona. Ad esempio, SELECT DATEDIFF(second, DATEADD(minute, -15, GETUTCDATE()), GETUTCDATE()) / 3600.0restituisce 0,250000.
Phil Ross

15

Basta sottrarre i due valori datetime e moltiplicarli per 24:

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

uno script di test potrebbe essere:

  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

Questo funziona perché tutti i datetimes sono memorizzati internamente come una coppia di numeri interi, il primo numero intero è il numero di giorni dal 1 gennaio 1900 e il secondo numero intero (che rappresenta l'ora) è il numero di ( 1 ) tick dalla mezzanotte. (Per SmallDatetimes la parte intera del tempo è il numero di minuti trascorsi dalla mezzanotte). Qualsiasi aritmetica eseguita sui valori utilizza la porzione di tempo come frazione di un giorno. 6am = 0.25, mezzogiorno = 0.5, ecc ... Vedi link MSDN qui per maggiori dettagli.

Quindi Cast ((@ Dt2 - @ Dt1) as Float) ti dà i giorni totali tra due datetimes. Moltiplica per 24 per convertire in ore. Se hai bisogno di minuti totali, più minuti al giorno (24 * 60 = 1440) invece di 24 ...

NOTA 1 : non è la stessa cosa di un segno di spunta dotNet o javaScript: questo segno di spunta è di circa 3,33 millisecondi.


Bel trucco. SQL dovrebbe includere una costante denominata. Mi sentivo sporco quando scrivevo 24, ma immagino che sia quello che ottengo per non essere Ronald McDonald.
Allen

10

DATEDIFF ma nota che restituisce un numero intero quindi se hai bisogno di frazioni di ore usa qualcosa del genere: -

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

2

Utilizzando Postgres ho avuto problemi con DATEDIFF, ma ho avuto successo con questo:

  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

che mi ha dato un output come "14.3"


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

Risultato = 1,00


1
DateDiff () restituisce un int. Potresti lanciare in decimale, ma la mantissa è già troncata.
Joel Coehoorn,

0

Probabilmente stai cercando la funzione DATEDIFF .

DATEDIFF (datepart, startdate, enddate)

Dove il codice potrebbe essere simile a questo:

DATEDIFF (hh, startdate, enddate)


1
L'intervallo "hh" non farà quello che vuole. Ha bisogno di un intervallo più piccolo in modo da poter calcolare le ore frazionarie.
Joel Coehoorn,

0
DATEDIFF(minute,startdate,enddate)/60.0)

Oppure usalo per 2 cifre decimali:

CAST(DATEDIFF(minute,startdate,enddate)/60.0 as decimal(18,2))

-1

SELEZIONA DATEDIFF (hh, firstDate, secondDate) FROM tableName WHERE ...


DateDiff () restituisce un int. Potresti lanciare in decimale, ma la mantissa è già troncata.
Joel Coehoorn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.