Find duration in hh:mm:ss in SQL Server - sql-server

I have starttime and endtime columns in my table and I want to get time difference between the two. But however I want the difference in hh:mm:ss format which I am not getting.
Declare #starttime = '7/23/2020 3:30:02 PM'
Declare #endtime = '7/23/2020 3:30:07 PM'
Select cast(#starttime - #endtime as Time) As Timedifference
I get 00:00:05.000000 which I don't want.

This may help you:
select convert(varchar(5),DateDiff(s, #startDate, #EndDate)/3600)+':'
+convert(varchar(5),DateDiff(s, #startDate, #EndDate)%3600/60)+':'
+convert(varchar(5),(DateDiff(s, #startDate, #EndDate)%60)) as [hh:mm:ss]

From SQL Server 2012 you can use FORMAT function.
In the following post you can find many solutions of this:
SQL time difference between two dates result in hh:mm:ss
Below the best solution if you have SQL Server 2012 or later version:
--get the difference between two datetimes in the format: 'hh:mm:ss'
CREATE FUNCTION getDateDiff(#startDate DATETIME, #endDate DATETIME)
RETURNS VARCHAR(10)
AS BEGIN
DECLARE #seconds INT = DATEDIFF(s, #startDate, #endDate)
DECLARE #difference VARCHAR(10) =
FORMAT(#seconds / 3600, '00') + ':' +
FORMAT(#seconds % 3600 / 60, '00') + ':' +
FORMAT(#seconds % 60, '00')
RETURN #difference
END
For FORMAT documentation look here

Related

Time difference with hours, minutes and seconds in SQL Server

I need to find time difference between two columns with hours, minutes and seconds.
These are two datetime columns in my table:
STOP_TIME Start_Time
------------------------------------------------------
2016-05-10 03:31:00.000 2016-05-10 02:25:34.000
I calculated second difference for stoptime and starttime. 3926 is the second difference.
I need to convert this to time format hh:mm:ss.
This should work for you -
DECLARE #STOP_TIME DATETIME = '2016-05-10 03:31:00.000',
#Start_Time DATETIME = '2016-05-10 02:25:34.000'
SELECT
RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) / 3600 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) % 3600/60 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) % 60 AS VARCHAR(2)),2)
Sql server supports adding and subtracting on Datetime data type, so you can simply do something like this:
DECLARE #StartTime datetime = '2016-05-10 02:25:34.000',
#EndTime datetime = '2016-05-10 03:31:00.000'
SELECT CAST(#EndTime - #StartTime as Time) As TimeDifference
Result: 01:05:26
Note: As TT rightfully wrote in his comment, casting to time will only work if the difference between #EndTime and #StartTime is less then 24 hours.
If you need to compare times that are further apart, you need to use one of the other solutions suggested.

Replace only the date part

This question may be duplicate sorry for it,As I could not able to find any solution in web till now so am Posting this
I need to create a SQL server functions where I need to replace only the date part from the actual date ..
For example if the actual date is 01/10/2016 means I need to update the actual date to 15/10/2016 the date part alone is replaced from 01 to 15 I need to achieve this, please help me in solving this as am very new to SQL SERVER
DECLARE #actual_due_date INT = 5;
DECLARE #invoice_date DATETIME = '20161210';
DECLARE #due_date DATETIME;
SET #due_date=DATEADD(DAY,#actual_due_date-DATEPART(DAY,#invoice_date),#invoice_date);
SELECT #due_date;
This prints out
2016-12-05 00:00:00.000
Here's another way to do it:
DECLARE #oldDate DATETIME = '2016-10-17 10:29:22'
DECLARE #replacingDate DATE = '2016-10-15'
DECLARE #newDate DATETIME
SET #newDate = CONVERT(datetime, CONVERT(varchar, #replacingDate)+' '+ LEFT(CONVERT(varchar, CONVERT(time, #oldDate)), 8))
SELECT #newDate
--UPDATE TableA
--SET FieldX = CONVERT(datetime, CONVERT(varchar, #replacingDate)+' '+ LEFT(CONVERT(varchar, CONVERT(time, #oldDate)), 8))
--WHERE SomeCondition
Don't know, what you really try to achieve, but you could try this:
DECLARE #OtherDate DATETIME = {ts'2016-02-05 12:00:00'}; --Some day in February, 12 o'clock
DECLARE #actualDate DATETIME = GETDATE(); --current day and time
--This comes back with the other date, but the actual time
SELECT CAST(CAST(#OtherDate AS date) AS datetime) + CAST(CAST(#actualDate AS time) AS datetime);
Not sure of the purpose, why you are replacing it.
Here is one way:
Declare #date date = '01/10/2016'
Select Replace(Convert(varchar(20), #date, 101), '01/', '15/') AS ReplacedDate
-- 15/10/2016

TSQL Month and Year to Date Conversion

I have a table that stores an int for month and year. I need to convert that to a date (we can use the first day of the month and the day).
I tried something like below but got an error about converting int to date
AND CAST(ym.year + '-' + ym.month + '-' + '01' AS DATE) BETWEEN #startDate AND #endDate
End result should be be something like 2016-05-01 so I can check the date against a start and end date that I pass to the function.
You could try something like this, modified for your use:
declare #YY int = 2016
declare #MM int = 5
select CAST(CAST(#YY as varchar(4)) + '-' + RIGHT('00' + CAST(#MM as varchar(2)),2) + '-01' as DATE)
From SQL Server 2012 on you can use DATEFROMPARTS
AND DATEFROMPARTS(ym.year, ym.month, 1) BETWEEN #startDate AND #endDate
AND DateFromParts(ym.year, ym.month, 1) BETWEEN #startDate AND #endDate
EDIT: For old versions of SQL:
SELECT CAST(CAST(ym.year*10000+ym.month*100+1 AS CHAR(8)) AS DATETIME)
Try this :
CAST(CAST(ym.year AS varchar) + '-' + CAST(ym.month AS varchar) + '-01' AS DATETIME)
This will work if you are on 2008 or lower
select cast(
cast(ym.year as varchar(4))+
case when len(ym.month) < 2 then '0' + cast(ym.month as varchar(2)) else cast(ym.month as varchar(2)) end +
'01' as date)
The Error you are getting is because when you CONCAT your INT values there is no leading 0 for days before 10, or months before October, thus your CAST to DATE is essentially missing values to do the conversion. Here we are padding based off the length.
You could go the data way and create a table of year, month and date as first of month then join the tables. this may be faster for a large table especially if the number of years and months in the original table is limited.
So if you have a years data in your original table there would only be 12 records required, which as a join added into your processing should be quick.
To avoid missing dates, build the lookup table from original data:
SELECT year, month, cast(cast(year*10000+month*100+1 as char(8)) as date) as FirstOfMonth
INTO #FirstOfMonth FROM mytable GROUP BY year, month

SQL Selecting only records matching year and month between two dates

I am making a SQL procedure to get me a selection of workers from the table,
where each worker has startJob and endJob date.
What I need is to make selection of all the workers who were on the job
during specified #year and #month. (#year & #month are input params)
I would really appreciate an advice how to solve this the easiest way.
Thx for any help.
If i proper understood you then try something like:
CREATE PROCEDURE [usp_Procedure]
#Year int
, #Month int
AS
BEGIN
select * from workers
where #Year between YEAR(startJob) and YEAR(endJob)
and #Month between MONTH(startJob) and MONTH(endJob)
END
You can make a date from the year and month parameters and compare to the start and end job fields.
This will return the first day of the month/year entered, and return results where this date is between the StartJob and EndJob
select *
from worker
where
CAST(
CAST(#Year AS VARCHAR(4)) +
RIGHT('0' + CAST(#month AS VARCHAR(2)), 2) +
RIGHT('0' + CAST(01 AS VARCHAR(2)), 2)
AS DATETIME)
between
StartJob and EndJob
Create a DATE based on the start of the month for the given year
DECLARE #Year INT = 1999
DECLARE #Month INT = 1
DECLARE #Date DATE = CONVERT(DATE, CONVERT(CHAR, #Month) + '-' + CONVERT(CHAR, #Month) + '-01')
-- SQL Server should now correctly handle the logic to filter out the relevant rows
SELECT *
FROM worker w
WHERE #Date BETWEEN w.startJob AND w.endJob
If you'd rather use the last day of the month, then you could use EOMONTH(#Month) for your DAY.
FINAL SOLVED SELECT ROWS BETWEEN TWO DATE USING ONLY MONTH AND YEAR
begin
declare #trvl_start_date as date
declare #trvl_stop_date as date
declare #trim_start as varchar(20)
declare #trim_end as varchar(20)
declare #trvl_start_date_new as date
declare #trvl_stop_date_new as date
set #trvl_start_date ='2015-10-12'
set #trvl_stop_date='2016-01-01'
set #trim_start = LEFT(#trvl_start_date, CHARINDEX('-', #trvl_start_date) + 2) + '-01'
set #trim_end = LEFT(#trvl_stop_date, CHARINDEX('-', #trvl_stop_date) + 2) + '-01'
print #trim_start
print #trim_end
set #trvl_start_date_new = #trim_start
set #trvl_stop_date_new =dateadd(month,-1,#trim_end)
print #trvl_start_date_new
print #trvl_stop_date_new
SELECT fee_catg_srno FROM dbo.fee_catg_tbl
WHERE (acd_yr = 1) AND (recycle = 1) AND (acc_head_srno = 3) AND pay_date between #trvl_start_date_new and #trvl_stop_date_new
end

In TSQL, how would you convert from an int to a datetime and give the age?

What would be the sql for the following,
I have a date of birth in an int field,
ie YYYYMMDD = 19600518
I would like to get the age.
None of the other answers are actually calculating age. They're calculating the number of year boundaries and not taking the birthday into account.
To calculate the age, you'll need to do something like this:
DECLARE #d DATETIME
SET #d = CONVERT(DATETIME, CONVERT(VARCHAR(8), 19600518), 112)
SELECT DATEDIFF(year, #d, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, #d, GETDATE()), #d) <= GETDATE()
THEN 0 ELSE 1 END AS Age
Most of the other answers are not calculating age - just whole years (e.g. Jan 1 2009 is one "year" after Dec 31 2008). Thus, if you use most of the calculations on this page, you will return an incorrect age for half of the year, on average. Luke is the only person who has seen this but his answer strikes me as too complicated - there is an easier way:
Select CAST(DATEDIFF(hh, [birthdate], GETDATE()) / 8766 AS int) AS Age
(NOTE: Thanks go to 'Learning' for making a great catch on my original algorithm - this is a revision that uses hours instead of days)
Because the rounding here is very granular, this is almost perfectly accurate for every day of every year. The exceptions are so convoluted that they are almost humorous: every fourth year the age returned will be one year too young if we A) ask for the age before 6:00 AM, B) on the person's birthday and C) their birthday is after February 28th. Of course, depending on what time someone was born this might 'technically' be correct! In my setting, this is a perfectly acceptable compromise.
Here is a loop that prints out ages to show that this works.
Declare #age int;
Declare #BirthDate datetime;
Declare #Year int;
Set #Year = 2008;
WHILE (#Year > 1930)
BEGIN
-- Put today's date where you see '-03-18'
SET #BirthDate = CAST(Cast(#Year as varchar(4)) + '-03-18' AS DATETIME)
SELECT #age=CAST(DATEDIFF(hh, #BirthDate, GETDATE()) / 8766 AS int);
Print Cast(#Year as varchar) + ' Age: ' + Cast(#age as varchar);
Set #Year = #Year - 1;
END;
Finally, this is the version that will also convert Paul's integer date to a real date:
CAST(DATEDIFF(hh, Convert(Datetime, Convert(varchar(8), [birthdate]), 112), GETDATE()) / 8766 AS int) AS Age
DECLARE #dateSt VARCHAR(8)
DECLARE #startDt DATETIME
-- Set the start date string
SET #dateSt = '19600518'
-- Make it a DATETIME (the ISO way)
SET #startDt = CAST(SUBSTRING(#dateSt, 1, 4) + '-' +
SUBSTRING(#dateSt, 5, 2) + '-' +
SUBSTRING(#dateSt, 7, 2) AS DATETIME)
-- Age in Days
SELECT DATEDIFF(D, #startDt, getdate())
Age in years :
select datediff(YY, convert(datetime, convert(varchar, 19600518)), getdate())
[EDIT]
-- I forgot to declare the variables
declare #birthday datetime;
set #birthday = convert(datetime,convert(varchar, 19600518), 112);
declare #datetoday datetime;
set #datetoday = getdate();
select
(
CASE
WHEN dateadd(year, datediff (year, #birthday, #datetoday), #birthday) <= #datetoday
THEN datediff (year, #birthday, #datetoday)
ELSE datediff (year, #birthday, #datetoday) - 1
END) as age;
Here's a one-liner way to do it:
CONVERT(DATETIME, CONVERT(VARCHAR(8),19600518), 112)
But beware! This relies on T-SQL, and probably won't work in other SQL environments.
Please note that the "style" of 112 is simply the "ISO" date format of yyyymmdd. (Something I found in some CONVERT documentation.)
This is a reason why you should NOT ever store dates as anything except a datetime datatype. The best fix is to change your datatype and convert all the dates once (wouldn't be surprised if there are few invalid ones in there either). then you never have to do these workarounds again.
I worked it out and got same as #Learning
select dob, datediff(year, convert(datetime, convert(varchar(8),[dob])) ,getdate()) as age
from [mytable]
where IsDate(convert(varchar(8),[dob])) = 1
NB. I needed the IsDate as well as there were some invalid dates in the data.
Edit. Here is an article from SQLServerCentral on calculating age.

Resources