Time Diff Calculation [on hold] - sql-server

This is my data:
How can I calculate the time difference: so in this case it should be 08:26:00 ?
The column in 'Vrijeme'

Just check this sample
CREATE TABLE #T
(
Id INT,
Vrijeme TIME,
datum DATE
);
INSERT #T
VALUES
(34, '06:43:00', '01.04.2019'),
(35, '15:09:00', '01.04.2019');
DECLARE #Date1 DATETIME =
(
SELECT DATEADD(ms, DATEDIFF(ms, '00:00:00', Vrijeme), CONVERT(DATETIME, datum))
FROM #T
WHERE Id = 34
)
DECLARE #Date2 DATETIME =
(
SELECT DATEADD(ms, DATEDIFF(ms, '00:00:00', Vrijeme), CONVERT(DATETIME, datum))
FROM #T
WHERE Id = 35
)
SELECT DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60 * 24) AS Day,
DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60) % 24 AS Hour,
DATEDIFF(SECOND, #Date1, #Date2) / (60) % 60 AS Minute,
DATEDIFF(SECOND, #Date1, #Date2) % 60 AS Second
SELECT CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60 * 24) AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60) % 24 AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60) % 60 AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) % 60 AS VARCHAR) AS Diff
DROP TABLE #T
and try CTE, LAG() to calculate time diff for each row :
WITH CTE AS(
SELECT Id , DATEADD(ms, DATEDIFF(ms, '00:00:00', Vrijeme), CONVERT(DATETIME, datum)) AS Date1,
LAG(DATEADD(ms, DATEDIFF(ms, '00:00:00', Vrijeme), CONVERT(DATETIME, datum)), 1) OVER (ORDER BY Id) AS Date2,
CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60 * 24) AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60 * 60) % 24 AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) / (60) % 60 AS VARCHAR) + ':'
+ CAST(DATEDIFF(SECOND, #Date1, #Date2) % 60 AS VARCHAR) AS Diff
FROM #T)
SELECT * FROM CTE

Related

SQL Server function to convert Unix time to local datetime

I'm looking for an efficient SQL Server function (in my case 2005) to convert a unix time value into a SQL Server datetime, using local time (particularly taking account of summertime adjustments - i.e not just adding 01/01/1970 in seconds)
SELECT DATEADD(second, #ts, {d '1970-01-01'}) as MSSQLdatetime
After you have the date, you can now do dateadd on the date depending on the DST state for the returned date. To check for DST you need some form of function, sample:
CREATE function [dbo].[fn_GetDaylightSavingsTimeStart]
(#Year varchar(4))
RETURNS smalldatetime
as
begin
declare #DTSStartWeek smalldatetime, #DTSEndWeek smalldatetime
set #DTSStartWeek = '03/01/' + convert(varchar,#Year)
return case datepart(dw,#DTSStartWeek)
when 1 then
dateadd(hour,170,#DTSStartWeek)
when 2 then
dateadd(hour,314,#DTSStartWeek)
when 3 then
dateadd(hour,290,#DTSStartWeek)
when 4 then
dateadd(hour,266,#DTSStartWeek)
when 5 then
dateadd(hour,242,#DTSStartWeek)
when 6 then
dateadd(hour,218,#DTSStartWeek)
when 7 then
dateadd(hour,194,#DTSStartWeek)
end
end
You need a simular function to find when DST ends, take a look at this site for more info:
http://www.mssqltips.com/tip.asp?tip=1372
better?
CREATE FUNCTION [dbo].[UnixTimestampToGMTDatetime]
(#UnixTimestamp bigint)
RETURNS datetime
AS
BEGIN
DECLARE #GMTDatetime datetime
select #GMTDatetime =
CASE
WHEN dateadd(ss, #UnixTimestamp/1000, '1970-01-01')
BETWEEN
Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, #UnixTimestamp/1000, '1970-01-01') )) + '-03-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, #UnixTimestamp/1000, '1970-01-01') )/4 + 4) % 7)) + ' 01:00:00', 20)
AND
Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, #UnixTimestamp/1000, '1970-01-01') )) + '-10-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, #UnixTimestamp/1000, '1970-01-01') )/4 + 1) % 7)) + ' 02:00:00', 20)
THEN Dateadd(hh, 1, dateadd(ss, #UnixTimestamp/1000, '1970-01-01'))
ELSE Dateadd(hh, 0, dateadd(ss, #UnixTimestamp/1000, '1970-01-01'))
END
RETURN #GMTDatetime
END

DATEADD MINUTES Between Range MSSQL

I am having some difficulty in trying to figure out something, lets say I have a date and time;
And I want to add 180 minutes to it so;
SELECT DATEADD(MINUTE,180,'2018-05-24 15:00')
This would give me answer of "2018-05-24 18:00" but I want to do it in a range so ADD the minutes if you are between 09:00 - 17:00 so something like this;
SELECT DATEADD(MINUTES,180,'2018-05-24 15:00') WHERE '2018-05-24 15:00' BETWEEN '2018-05-24 09:00' AND '2018-05-24 17:00'
So the answer to this would be "2018-05-25 10:00"
Was hard, but this should work for all your cases. This solution works for any amount of (positive) minutes and result will always be inside the parametrized hours, adding the corresponding amount of days.
DECLARE #RangeHourStart INT = 9
DECLARE #RangeHourEnd INT = 17
DECLARE #MinutesToAdd INT = 120
DECLARE #Date DATETIME = '2018-05-24 15:00'
SELECT
FinalDate = CASE
WHEN -- When final hour exceeds the range hour
DATEPART(HOUR, #Date) * 60 +
DATEPART(MINUTE, #Date) +
#MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60) > #RangeHourEnd * 60
THEN
DATEADD(HOUR, -1 * (#RangeHourStart - 1),
DATEADD(DAY, 1,
DATEADD(MINUTE, #MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60),
DATEADD(
DAY,
#MinutesToAdd / ((#RangeHourEnd - #RangeHourStart) * 60),
#Date))))
ELSE
DATEADD(MINUTE, #MinutesToAdd % ((#RangeHourEnd - #RangeHourStart) * 60),
DATEADD(
DAY,
#MinutesToAdd / ((#RangeHourEnd - #RangeHourStart) * 60),
#Date))
END
I made it so you don't need to hard-code any value.
This doesn't look particularly pretty, however...
USE Sandbox;
GO
CREATE TABLE Times (DateNTime datetime2(0));
INSERT INTO Times
VALUES ('20180520 10:00:00'),
('20180520 15:20:00'),
('20180521 09:32:00'),
('20180521 14:17:00'),
('20180522 16:54:00'),
('20180523 12:46:00'),
('20180524 15:32:00');
GO
SELECT *
FROM Times;
GO
SELECT T.DateNTime,
CASE WHEN CONVERT(time,T.DateNTime) <= '14:00' THEN DATEADD(MINUTE, 180,T.DateNTime)
ELSE DATEADD(MINUTE, 180 - DATEDIFF(MINUTE,T.DateNTime,DATEADD(HOUR,17,DATEADD(DAY, DATEDIFF(DAY, 0, T.DateNTime),0))), DATEADD(HOUR,9,DATEADD(DAY, DATEDIFF(DAY, 0, T.DateNTime) + 1,0))) END
FROM Times T;
GO
DROP TABLE Times;
you can try this:
DECLARE #input DATETIME='2018-05-24 15:00'
DECLARE #min INT=180
SELECT CASE WHEN DATEADD(MINUTE,#min,#input)>DATEADD(HOUR, 17,DateAdd(Day, Datediff(Day,0, #input), 0))
THEN DATEADD(MINUTE,
DATEDIFF(MINUTE,
DATEADD(HOUR, 17,
DATEADD(Day,
DATEDIFF(Day,0, #input),
0)
),
DATEADD(MINUTE,#min,#input)),
DATEADD(Hour,9,
DATEADD(Day,1,
DateAdd(Day,
Datediff(Day,0, #input),
0)
)
)
)
ELSE DATEADD(MINUTE,#min,#input)
END

Calculate Time Difference in hh:mm

I have this query but I'm not sure what function to use so I can get time difference in this "hh:mm" format. Can anybody help ?
SELECT
EI.[FirstName]+' '+EI.[LastName] [EmployeeName], [Dpt].[FullName] [Department], [Desig].[FullName] [Designation],
FirstIN = CAST(MIN([AttendanceTimeIn]) AS TIME),
LastOUT = CAST(MAX([AttendanceTimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(AttendanceTimeIn) AS TIME), CAST(MAX(AttendanceTimeOut) AS TIME)),
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE) [Date]
FROM [HRM].[tbl_Designation] [Desig], [HRM].[tbl_Department] [Dpt], [HRM].[tbl_EmployeeInfo] [EI]
FULL OUTER JOIN [HRM].[tbl_EmployeeAttendance] [Attendance] ON [Attendance].[EmpCode] = [EI].[ID]
WHERE
[Dpt].[ID] = [EI].[DeptCode] AND [Desig].[ID] = [EI].[DesignationCode]
AND
[EI].[RecordStatusCode] != '13'
AND
CAST((GETDATE()-1) AS DATE) = CAST(ISNULL([AttendanceTimeIn], [AttendanceTimeOut]) AS Date)
GROUP BY
EI.[FirstName]+' '+EI.[LastName], [Dpt].[FullName], [Desig].[FullName], CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE)
Maybe you can use something like this:
declare #d1 datetime = '2018-01-11 23:40:18.010'
declare #d2 datetime = '2018-01-12 11:59:18.010'
SELECT CONVERT(VARCHAR(2),DATEPART(HOUR,#d2 - #d1)) + ':' + CONVERT(VARCHAR(2),DATEPART(MINUTE,#d2 - #d1));
If to leave out your concept of using the time for the duration, you can use a query like below:
DECLARE #d1 DATETIME
DECLARE #d2 DATETIME
SELECT #d1 = GETDATE() - 1.465, #d2 = GETDATE()
SELECT
FirstIN = #d1,
LastOUT = #d2,
HoursSpent = CAST(DATEDIFF(HOUR, #d1, #d2) AS VARCHAR) + ':' + RIGHT('0' + CAST(DATEDIFF(MINUTE, #d1, #d2) % 60 AS VARCHAR), 2)
Let's expand step by step:
declare
#start datetime = getdate(),
#end datetime = dateadd(second, getdate(), 5000)
-- datediff(hour, #start, #end) -> hour difference
-- dateadd(hour, #start, datediff(hour, #start, #end)) -> start + integer hour difference to get less-than-an-hour diff
-- datediff(minute, dateadd(hour, #start, datediff(hour, #start, #end)), #end) -> minute difference from there
select
cast(datediff(hour, #start, #end) as varchar(2))
+ ':'
+ cast(datediff(minute, dateadd(hour, #start, datediff(hour, #start, #end)), #end) as varchar(2)) as [hh:mm]

Calculate time difference in HH:MM:SS

I am trying to get the time difference between 2 times. I have a query which calculate the time in hours but what I want is to calculate in this (hh:mm) or (hh:mm:ss) format.
Is there any function or way I can achieve this ?
DECLARE #T TABLE
([EmpID] int, [TimeIn] datetime, [TimeOut] datetime);
INSERT INTO #T
([EmpID], [TimeIn], [TimeOut]) VALUES
(1, '2018-01-10 9:00:00', NULL),
(1, NULL, '2018-01-10 11:00'),
(1, '2018-01-10 11:30:00', NULL),
(1, NULL, '2018-01-10 13:00'),
(1, '2018-01-10 13:30:00', NULL),
(1, NULL, '2018-01-10 18:00'),
(1, '2018-01-11 9:00:00', NULL),
(1, NULL, '2018-01-11 11:00'),
(1, '2018-01-11 11:30:00', NULL),
(1, NULL, '2018-01-11 13:00'),
(1, '2018-01-11 13:30:00', NULL),
(1, NULL, '2018-01-11 18:33')
;
SELECT
FirstIN = CAST(MIN([AttendanceTimeIn]) AS TIME),
LastOUT = CAST(MAX([AttendanceTimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(AttendanceTimeIn) AS TIME), CAST(MAX(AttendanceTimeOut) AS TIME)),
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE) [Date]
FROM #T
GROUP BY
CAST(COALESCE(AttendanceTimeIn, AttendanceTimeOut) AS DATE)
You can use this for With DATETIME
DECLARE #START_DATE datetime DECLARE #END_DATE datetime
-- Set the timeframe variables
SET #START_DATE = '2011-01-01 16:00:00' SET #END_DATE = '2011-01-01 22:47:22'
-- Use datediff to show the results in the
-- HH:MM:SS format
SELECT CONVERT(VARCHAR(6), datediff(second, #START_DATE, #END_DATE)/3600) + ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (datediff(second, #START_DATE, #END_DATE) %
3600) / 60), 2) + ':' + RIGHT('0' + CONVERT(VARCHAR(2), datediff(second,
#START_DATE, #END_DATE) % 60), 2)
Result :
HH:MM:SS
6:47:22
OR With TIME
-- Declare some variables for the requested timeframe
DECLARE #START_DATE TIME
DECLARE #END_DATE TIME-- Set the timeframe variables
SET #START_DATE = '16:00:00'
SET #END_DATE = '22:47:22'-- Use datediff to show the results in the
-- HH:MM:SS format
SELECT CONVERT(VARCHAR(6), Datediff(second, #START_DATE, #END_DATE)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, #START_DATE,
#END_DATE) %
3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, #START_DATE, #END_DATE
) % 60)
, 2) AS 'HH:MM:SS'
AS Per Edit
;
WITH cte
AS (SELECT EMPID,
Min(TIMEIN) timein,
Max(TIMEOUT) timeout,
Cast(COALESCE(TIMEIN, TIMEOUT) AS DATE) d
FROM #T
GROUP BY EMPID,
Cast(COALESCE(TIMEIN, TIMEOUT) AS DATE))
SELECT EMPID,
D AS Day,
CONVERT(VARCHAR(6), Datediff(second, TIMEIN, TIMEOUT)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, TIMEIN, TIMEOUT) %
3600) /
60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, TIMEIN, TIMEOUT) % 60)
, 2 )
AS [Hours Worked]
FROM cte
ORDER BY D ASC
Result
empid Day Hours Worked
1 2018-01-10 9:00:00
1 2018-01-11 9:33:00
Resolve After Mistake of preiviuos senario
SELECT FirstIN, LastOUT,
CONVERT(VARCHAR(6), Datediff(second, FirstIN, LastOUT)/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, FirstIN, LastOUT) %
3600) /
60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, FirstIN, LastOUT) % 60)
, 2 ) AS
HoursSpent,[Date] FROM (
SELECT
FirstIN = CAST(MIN([TimeIn]) AS TIME),
LastOUT = CAST(MAX([TimeOut]) AS TIME),
HoursSpent = DATEDIFF(HOUR, CAST(MIN(TimeIn) AS TIME), CAST(MAX(TimeOut) AS TIME)),
CAST(COALESCE(TimeIn, TimeOut) AS DATE) [Date]
FROM #T
GROUP BY
CAST(COALESCE(TimeIn, TimeOut) AS DATE)) AS a
Check this snippet which returns difference at seconds level (HH:mm:ss)
SELECT CONVERT(time,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
If you need HH:mm only change 's' for 'mi'
And if you need difference in days too use this one:
SELECT CONVERT(datetime2,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('0001-01-01 00:00:00.0000000' as datetime2)
)
)

How to add two time(like 10:30:16,14:27:44) in sql server 2008

I have two columns as shown in below
InTime OutTime
10:30:16 10:10:11
14:27:44 13:47:55
9:35:01 18:31:51
Now i need to sum intime column values and outtime column values seperatly then dofference between both output values in sql server 2008.Please any one help me.
Output:
Intime Outtime
34:33:01 42:29:57
difference output:
7:56:56
SQL server specially don't have any function to add and subtract time but if you need you can use
DATE_SUB()
DATE_ADD()
By putting same date in each time
http://www.w3schools.com/sql/func_date_add.asp
http://www.w3schools.com/sql/func_date_sub.asp
Because Sql Server time type may contain up to 24 hours you can return varchar type as:
select cast(tm / 3600 as varchar(20)) + ':' +
cast((tm - tm % 60) / 60 % 60 as varchar(20)) + ':' +
cast(tm % 60 as varchar(20))
from (select sum(datediff(ss, timein, timeout)) tm from t) t
Fiddle http://sqlfiddle.com/#!3/f20de/19
You can do it just like that. It is not nice but you can write help functions to format data (select return nvarchar becouse time in sql server can not reach more then 24 h):
create table #TMP
(
InTime time,
OutTime time
)
INSERT INTO #TMP (InTime, OutTime) VALUES ('10:30:16', '10:10:11')
INSERT INTO #TMP (InTime, OutTime) VALUES ('14:27:44', '13:47:55')
INSERT INTO #TMP (InTime, OutTime) VALUES ('9:35:01', '18:31:51')
select CAST(InTime/3600 as nvarchar(5)) + ':' + CASE WHEN ((InTime%3600)/60) > 9 THEN '' ELSE '0' END + CAST((InTime%3600)/60 as nvarchar(5)) + ':' + CASE WHEN ((InTime%3600)%60) > 9 THEN '' ELSE '0' END + CAST((InTime%3600)%60 as nvarchar(5)) as SumIn,
CAST(OutTime/3600 as nvarchar(5)) + ':' + CASE WHEN ((OutTime%3600)/60) > 9 THEN '' ELSE '0' END + CAST((OutTime%3600)/60 as nvarchar(5)) + ':' + CASE WHEN ((OutTime%3600)%60) > 9 THEN '' ELSE '0' END+ CAST((OutTime%3600)%60 as nvarchar(5)) as SumOut,
CAST(Diff/3600 as nvarchar(5)) + ':' + CASE WHEN ((Diff%3600)/60) > 9 THEN '' ELSE '0' END + CAST((Diff%3600)/60 as nvarchar(5)) + ':' + CASE WHEN ((Diff%3600)%60) > 9 THEN '' ELSE '0' END+ CAST((Diff%3600)%60 as nvarchar(5)) as Diff
from
(
select SUM(datediff(SECOND, '00:00:00', InTime)) as InTime, SUM(datediff(SECOND, '00:00:00', OutTime)) as OutTime,
SUM(datediff(SECOND, '00:00:00', OutTime)) - SUM(datediff(SECOND, '00:00:00', InTime)) as Diff
from #TMP
) X
CASE is for format data to have 34:33:01 not 34:33:1
There isn't built-in function on this.
But You can use this:
declare #t table (InTime time, OutTime time)
insert into #t values
('10:30:16', '10:10:11')
, ('14:24:44', '13:47:55')
, ('9:35:01', '18:31:51')
select convert(varchar(10),t.InTime/60/60)+':'+right('0'+convert(varchar(2),(t.InTime-t.InTime%60)/60%60),2)+':'+right('0'+convert(varchar(2),t.InTime%60),2) InTime
, convert(varchar(10),t.OutTime/60/60)+':'+right('0'+convert(varchar(2),(t.OutTime-t.OutTime%60)/60%60),2)+':'+right('0'+convert(varchar(2),t.OutTime%60),2) OutTime
, convert(varchar(10),t.DiffTime/60/60)+':'+right('0'+convert(varchar(2),(t.DiffTime-t.DiffTime%60)/60%60),2)+':'+right('0'+convert(varchar(2),t.DiffTime%60),2) DiffTime
from (
select sum(DATEPART(HOUR,InTime)*60*60 + DATEPART(MINUTE, InTime)*60 + DATEPART(SECOND, InTime)) InTime
, sum(DATEPART(HOUR,OutTime)*60*60 + DATEPART(MINUTE, OutTime)*60 + DATEPART(SECOND, OutTime)) OutTime
, sum(DATEDIFF(SECOND, InTime, OutTime)) DiffTime
from #t) t
Try this first calculate Intime and outTime sums in Seconds then get diffrences between both outtime - Intime .
SELECT cast( (TimeInseconds / 3600 ) AS varchar(10) ) + ':' +
cast( ((TimeInseconds % 3600) / 60)as varchar(10)) + ':' +
cast( (TimeInseconds % 60) AS varchar(10)) As Time
FROM (
SELECT (SUm(DatePart(HH, OutTime)) * 3600 + SUm(DatePart(MINUTE, OutTime)) * 60 + SUm(DatePart(SS, OutTime))) - (SUm(DatePart(HH, Intime)) * 3600 + SUm(DatePart(MINUTE, Intime)) * 60 + SUm(DatePart(SS, Intime))) AS TimeInseconds
FROM Intimes
) X
SQLFiddle

Resources