Чи є спосіб визначити різницю між двома datetime
на сервері SQL?
Наприклад, мої дати є
2010-01-22 15:29:55.090
2010-01-22 15:30:09.153
Отже, результат повинен бути 14.063 seconds
.
Чи є спосіб визначити різницю між двома datetime
на сервері SQL?
Наприклад, мої дати є
2010-01-22 15:29:55.090
2010-01-22 15:30:09.153
Отже, результат повинен бути 14.063 seconds
.
Відповіді:
Просто застереження, яке слід додати про 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 секунд, він буде повернутий як одна хвилина при використанні хвилин як одиниць.
SELECT DATEDIFF (MyUnits, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')
Замінити "MyUnits" на основі DATEDIFF на MSDN
Я можу згадати чотири важливі функції 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
Я спробував таким чином, і це спрацювало. Я використовував 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
Добре, ми всі знаємо, що відповідь передбачає 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
Внутрішньо в SQL Server дати зберігаються як 2 цілі числа. Перше ціле число - це кількість дат до або після базової дати (1900/01/01). Друге ціле число зберігає кількість годинникових тиків після опівночі, кожен тик становить 1/300 секунди.
Через це я часто знаходжу найпростіший спосіб порівняння дат - це просто їх вилучення. Це обробляє 90% випадків мого використання. Наприклад,
select date1, date2, date2 - date1 as DifferenceInDays
from MyTable
...
Коли мені потрібна відповідь в одиницях, крім днів, я буду використовувати DateDiff .
Існує декілька способів подивитися на різницю дат, а також при порівнянні дати та часу. Ось що я використовую, щоб отримати різницю між двома датами, відформатованими як "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
Наступний запит повинен дати точну інформацію, яку ви шукаєте.
select datediff(second, '2010-01-22 15:29:55.090' , '2010-01-22 15:30:09.153')
Ось посилання з MSDN на те, що все можна зробити за допомогою функції dateiff. https://msdn.microsoft.com/en-us/library/ms189794.aspx
SELECT DATEDIFF(yyyy, '2011/08/25', '2017/08/25') AS DateDiff
Це дає вам різницю між двома датами в році
Тут (2017-2011) = 6 як результат
Синтаксис:
DATEDIFF(interval, date1, date2)
Використовуйте це для 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)
Отже, це не моя відповідь, але я просто знайшов це під час пошуку в Інтернеті такого питання. Цей хлопець встановив процедуру обчислення годин, хвилин і секунд. Посилання та код:
--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'
)
ДРУКУВАТИ DATEDIFF (друге, '22.01.2010 15: 29: 55.090', '22.01.2010 15: 30: 09.153')
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
Просто подумав, що згадаю про це.
СТВОРИТИ ФУНКЦІЮ 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:
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 працює найкраще
Для мене це працювало ідеально Конвертувати (varchar (8), DATEADD (SECOND, DATEDIFF (SECOND, LogInTime, LogOutTime), 0), 114)
а вихід - HH: MM: SS, що точно показано в моєму випадку.
Перевірте DateDiff на Books Online.
datediff
відповіді, але, здається, жоден не нагадує вам, що ви можете отримати від нього негативні результати залежно від упорядкування параметрів.