Есть ли способ различить два 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 дням, датфик вернет значение 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
SELECT DATEDIFF(day, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')
Замените day
другими единицами, для которых вы хотите получить разницу, например second
, minute
и т.д.
Я могу упомянуть о четырех важных функциях MS SQL Server, которые могут быть очень полезными:
1) Функция DATEDIFF() несет ответственность за расчет различий между двумя датами, результат может быть " year month month dayyyear день недели, минуты секунды, миллисекундная микросекундная наносекунда", указанная по первому параметру (datepart):
select datediff(day,'1997-10-07','2011-09-11')
2) Вы можете использовать функцию GETDATE(), чтобы получить фактическое время и рассчитать разницу в какой-либо дате и фактической дате:
select datediff(day,'1997-10-07', getdate() )
3) Еще одна важная функция - DATEADD(), используемая для преобразования некоторого значения в datetime с использованием той же datepart (с положительными значениями) или вычитанием (с отрицательными значениями) на одну базовую дату:
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 холод рассчитывается в секундах, и один интересный результат, смешивающий эти четыре функции, заключается в том, чтобы показать разницу в размере um часов, минут и секунд (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 (638s = 600s + 38s = 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
Внутри 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 для всего, что вы можете сделать с функцией latiff. https://msdn.microsoft.com/en-us/library/ms189794.aspx
Хорошо, мы все знаем, что ответ включает DATEDIFF()
. Но это дает вам только половину результата, за которым вы можете быть. Что, если вы хотите получить результаты в удобочитаемом формате, в виде минут и секунд между двумя значениями DATETIME
?
Функции CONVERT()
, DATEADD()
и, конечно, DATEDIFF()
идеально подходят для более удобочитаемого результата, который ваши клиенты могут использовать вместо числа.
т.е.
CONVERT(varchar(5), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114)
Это даст вам что-то вроде:
HH: MM
Если вы хотите большей точности, просто увеличьте VARCHAR()
.
CONVERT(varchar(12), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114)
HH: MM.SS.MS
SELECT DATEDIFF(yyyy, '2011/08/25', '2017/08/25') AS DateDiff
Это дает вам разницу между двумя датами в году
Здесь (2017-2011) = 6 в результате
Синтаксис:
DATEDIFF(interval, date1, date2)
Так что это не мой ответ, но я просто нашел это во время поиска в Интернете и для такого вопроса. Этот парень настроил процедуру вычисления часов, минут и секунд. Ссылка и код:
--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'
)
declare @dt1 datetime='2012/06/13 08:11:12', @dt2 datetime='2012/06/12 02:11:12'
select CAST((@[email protected]) as time(0))
ПЕЧАТНЫЙ ДАТИФФ (второй, '2010-01-22 15: 29: 55.090', '2010-01-22 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
Просто подумал, что я бы сказал об этом.
CREATE FUNCTION getDateDiffHours (@fdate AS datetime, @tdate как дата-время) ВОЗВРАЩЕНИЯ varchar (50) В ВИДЕ НАЧАТЬ 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),@[email protected])
--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),@[email protected]) --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'
КОНЕЦ
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]
Соль-3:
select
DATEPART(hour,[EndTime]-[StartTime])
, DATEPART(minute,[EndTime]-[StartTime])
from
[YourTable]
Datepart работает лучше всего
Пожалуйста, проверьте ниже трюк, чтобы найти разницу дат между двумя датами
DATEDIFF(DAY,ordr.DocDate,RDR1.U_ProgDate) datedifff
где вы можете изменить свое требование по мере того, как вы хотите разницу дней, месяца или года или времени.
Отметьте DateDiff out on Books Online.
Для меня это сработало Perfect Convert (varchar (8), DATEADD (SECOND, DATEDIFF (SECOND, LogInTime, LogOutTime), 0), 114)
и вывод будет ЧЧ: ММ: СС, который показан точно в моем случае.
Используйте это для 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)