Різниця між двома датами часу на SQL-сервері


83

Чи є спосіб визначити різницю між двома datetimeна сервері SQL?

Наприклад, мої дати є

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

Отже, результат повинен бути 14.063 seconds.


2
Ви отримуєте всі datediffвідповіді, але, здається, жоден не нагадує вам, що ви можете отримати від нього негативні результати залежно від упорядкування параметрів.
Пасі Саволайнен,

Відповіді:


94

Просто застереження, яке слід додати про DateDiff, воно враховує, скільки разів ви переходите межу, яку ви вказали як свої одиниці, тому можуть виникати проблеми, якщо ви шукаєте точний інтервал часу. напр

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

дає відповідь 1, оскільки він перетнув межу з січня по лютий, тому, незважаючи на те, що проміжок становить 2 дні, dateiff поверне значення 1 - він перетнув межу 1 дати.

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

Дає значення 1, знову ж таки, він один раз пройшов межу хвилин, тому, хоча це приблизно 14 секунд, він буде повернутий як одна хвилина при використанні хвилин як одиниць.



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

Замінити dayз іншими пристроями ви хочете , щоб отримати різницю в, як second, і minuteт.д.


16

Я можу згадати чотири важливі функції MS SQL Server, які можуть бути дуже корисними:

1) Функція DATEDIFF () відповідає за обчислення різниць між двома датами, результатом може бути " рік квартал місяць день рік рік тиждень година хвилина секунда мілісекунда мікросекунда наносекунда ", вказана на першому параметрі ( дата ):

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

2) Ви можете скористатися функцією GETDATE (), щоб отримати фактичний час та обчислити різниці певної дати та фактичної дати:

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

3) Ще одна важлива функція DATEADD () , використовується для перетворення деякого значення в дати і часу , використовуючи той же DATEPART з DateDiff, що ви можете додати (з позитивними значеннями) або відняти (з негативними значеннями) на сьогоднішній день один базовий:

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 (638 с = 600 с + 38 с = 10 хвилин 38 секунд)

Інший приклад:

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

9

Я спробував таким чином, і це спрацювало. Я використовував 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

Добре, ми всі знаємо, що відповідь передбачає DATEDIFF(). Але це дає вам лише половину результату, якого ви можете переслідувати. Що робити, якщо ви хочете отримати результати у зручному для читання форматі, виражаючи хвилини та секунди між двома DATETIMEзначеннями?

В CONVERT(), DATEADD()і, звичайно ж DATEDIFF()функція ідеально підходить для більш легко читається результату , що ваші клієнти можуть використовувати, замість номера.

тобто

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

Це дасть вам щось на зразок:

ЧЧ: ММ

Якщо ви хочете отримати більшу точність, просто збільшіть VARCHAR().

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

HH: MM.SS.MS


5

Внутрішньо в SQL Server дати зберігаються як 2 цілі числа. Перше ціле число - це кількість дат до або після базової дати (1900/01/01). Друге ціле число зберігає кількість годинникових тиків після опівночі, кожен тик становить 1/300 секунди.

Більше інформації тут

Через це я часто знаходжу найпростіший спосіб порівняння дат - це просто їх вилучення. Це обробляє 90% випадків мого використання. Наприклад,

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

Коли мені потрібна відповідь в одиницях, крім днів, я буду використовувати DateDiff .


6
Зверніть увагу , що це стосується лише до старого DATETIMEтипу, а НЕ DATE, TIMEабо DATETIME2. Крім того, значення, яке повертається, буде іншим DATETIME, тому вам потрібно буде його привести, щоб отримати зрозумілу для людини кількість днів між датами.

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


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

Це дає вам різницю між двома датами в році

Тут (2017-2011) = 6 як результат

Синтаксис:

DATEDIFF(interval, date1, date2)

2

Використовуйте це для 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

Отже, це не моя відповідь, але я просто знайшов це під час пошуку в Інтернеті такого питання. Цей хлопець встановив процедуру обчислення годин, хвилин і секунд. Посилання та код:

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

Просто подумав, що згадаю про це.


1

СТВОРИТИ ФУНКЦІЮ getDateDiffHours (@fdate ЯК дата-час, @ tdate як дата-час) ВОЗВРАЩАЄ varchar (50) ЯК ПОЧАТИ ДЕКЛАРУВАТИ @cnt int ДЕКЛАРУВАТИ @cntDate дату ОГОЛОШИТИ @dayDiff int ДЕКЛАРУВАТИ @dayDiffWk int ДЕКЛАРА

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'

КІНЕЦЬ


1
Чи можете ви пояснити свій код відповідно до запитання?
користувач7294900

1

Соль-1:

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

Соль-2:

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

Соль-3:

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

Datepart працює найкраще


1

Будь ласка, ознайомтеся з приведеним нижче трюком, щоб знайти різницю дат між двома датами

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

де ви можете змінитись відповідно до ваших вимог, якщо хочете різницю в днях, місяці, році чи часі.


0

Для мене це працювало ідеально Конвертувати (varchar (8), DATEADD (SECOND, DATEDIFF (SECOND, LogInTime, LogOutTime), 0), 114)

а вихід - HH: MM: SS, що точно показано в моєму випадку.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.