I want to use a date-time picker to select a date as well as the time component. The calender allows me to pick a date but there's no possibility to choose the a specific time.
I want to choose a start and end time, to select a subset out of lot of a data.
I had a similar issue in my current project. My solution is to add a field for the date (type of date/time) and a field for the time. The time field will show a drop down list containing the 24 hours text for users to select (refer to attach screenshot below).
The steps to create the dropdown list is simple:
Open the propery of the time parameter of the report
Select Available Values (refer to attached screenshot below)
Select Specify values and add values to represent the 24 hours.
Please note, you can also set the available values from a query.
In addition, the stored procedure where the report data are retrieved should convert the date and time passed from the report to datetime type to get it work. Below shows a sample:
#StartDateTime = CONVERT(datetime, convert(nvarchar, #StartDate) +
' ' + CONVERT(nvarchar(12), #starttime))
Hope it helps.
I'm sure we have all found a way around this by now, however here is my solution.
CREATE PROCEDURE [ssrs].[Params_GetTimeTable]
(
#hr_from int = 0,
#hr_to int = 24,
#min_interval int = 15
)
AS
BEGIN
-- Internal Variables
declare #hr int = #hr_from
declare #min int = 0
declare #timetable table
(
hhmm varchar(5)
)
-- Populate the #timetable
while #hr < #hr_to
begin
while #min < 60
begin
insert into #timetable(hhmm)
select
case
when #hr < 10 then '0' + cast(#hr as varchar(2)) + ':' + case when #min < 10 then '0' + cast(#min as varchar(2)) else cast(#min as varchar(2)) end
else cast(#hr as varchar(2)) + ':' + case when #min < 10 then '0' + cast(#min as varchar(2)) else cast(#min as varchar(2)) end
end
set #min = #min + #min_interval
end
set #hr = #hr + 1
set #min = 0
end
-- Add a finishing time to the output table
insert into #timetable(hhmm)
select
case
when #hr < 10 then '0' + cast(#hr as varchar(2)) + ':00'
else cast(#hr as varchar(2)) + ':00'
end
-- Return the output
select hhmm from #timetable
END
Test the result by:
EXEC [ssrs].[Params_GetTimeTable] 0, 24, 15
Output :
hhmm
00:00
00:15
00:30
00:45
01:00
01:15
...
23:00
23:15
23:30
23:45
24:00
With the standard SSRS calendar picker, after you have selected a date, you can click in the textbox and manually enter the time value next to the selected date. I know this is not very user intuitive, but it does work.
I have the same problem, and am looking for a more user friendly solution, but this is all I can come with so far.
I use this SQL which generates times every 15mins between 9:00 and 21:00, people is just any table with at least enough rows i.e. 12 or 24.
select time1
from
(
select hr || ':' || mm time1
from
(
select '09' hr
from dual
union
select cast(rownum + 9 as varchar(2)) hr
from people
where rownum < 12
order by hr
)hr,
(
select '00' mm
from dual
union
select '15' mm
from dual
union
select '30' mm
from dual
union
select '45' mm
from dual
)mm
union
(
select '21:00' time1
from dual
)
)T1
order by time1
I use this as an integer parameter then you can add the number of minutes to whatever date is selected
DECLARE #interval INT = 15
;WITH cteM AS (
SELECT 0 M UNION ALL
SELECT M+#interval FROM cteM
WHERE M+#interval <= 59
),
cteH AS (
SELECT 0 H UNION ALL
SELECT H+1 FROM cteH
WHERE H+1 < 24
)
SELECT
RIGHT('0' + CAST(cteH.H AS varchar(2)), 2) + ':' + RIGHT('0' + CAST(cteM.M AS varchar(2)), 2) Label,
cteH.H*60 + cteM.M Value
FROM cteM CROSS JOIN cteH
Related
I have a list of months formatted with the 3 letter abbreviation followed by the last 2 numbers of the year.
For example, this current month would be SEP22. I need to find a way to turn this from a varchar into a date/datetime value, pointing to the first day of the month.
So, if I have 'SEP22', I need to get the output of September 1st, 2022 as a date/datetime object.
I can find a lot of data on turning the datetime value or numeric month into the abbreviation, but not the other way around.
I know I can make a giant case statement, but I was wondering if there's an easier method to read this type of data.
Any and all help is appreciated.
EDIT: I know the data is in the current century, I know where the data comes from and when it started being collected, all of this data has been collected in or after August 2013 (AUG13).
Try this:
SELECT
CAST(
LEFT(StringDate, 3) -- e.g. SEP
+' 1 20' -- assumes 21st century
+ RIGHT(StringDate, 2) -- e.g. 22
AS DATE
) AS ActualDate
;
For SQL Server:
convert(date, '01 ' + LEFT('SEP22', 3) + ' ' + RIGHT('SEP22', 2), 6)
When SQL Server converts the date from a string with a 2-digit year, the cutoff is at 50:
declare #myMonth table (
mo varchar(5)
)
declare #i int = 0
while #i < 100
begin
set #i = #i + 1
insert #myMonth
values ('SEP' + RIGHT('0' + CAST(#i AS VARCHAR(5)), 2))
end
SELECT mo
, convert(date, '01 ' + LEFT(mo, 3) + ' ' + RIGHT(mo, 2), 6)
FROM #myMonth
For Oracle:
TO_DATE('01' || 'SEP22', 'DDMONYY')
For Oracle, all of the dates are after 2000:
CREATE TABLE MYMONTH (
MO VARCHAR2(6) NOT NULL
)
;
INSERT INTO MYMONTH (MO)
SELECT 'SEP' || SUBSTR('0' || CAST(N AS VARCHAR2(5)), -2)
FROM (
SELECT (0 + ROWNUM) N
FROM DUAL CONNECT BY ROWNUM <= 100
)
;
SELECT MO
, TO_CHAR(TO_DATE('01' || MO, 'DDMONYY'), 'MM/DD/YYYY')
FROM MYMONTH
;
I'm going to write a code that round a datetime value but i can't compare which ones is more efficient:
DECLARE #DateValue DATETIME = '2021-01-13 11:59:59'
---- FIRST SOLUSTION:
SELECT CAST(#DateValue AS smalldatetime) AS DateRoundS1
---- SECOND SOLUTION:
SELECT CONVERT(smalldatetime, #DateValue) AS DateRoundS2
---- THIRD SOLUTION:
SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, #DateValue), 0) AS DateRoundS3
---- FORTH SOLUTION:
DECLARE #DateValue DATETIME = '2021-01-13 11:59:59'
DECLARE #DiffMinsTime INT = DATEPART(MINUTE,#DateValue)
DECLARE #DiffSecsTime INT = DATEPART(SECOND,#DateValue)
DECLARE #DiffMSTime INT = DATEPART(MILLISECOND,#DateValue)
IF( #DiffMinsTime > 0 )
BEGIN
SELECT DATEADD(MINUTE,DATEDIFF(MINUTE,#DiffMinsTime,#DateValue),0)
END
IF(#DiffSecsTime > 0)
BEGIN
SELECT DATEADD(SECOND,DATEDIFF(SECOND,#DiffSecsTime,#DateValue),0)
END
IF(#DiffMSTime > 0)
BEGIN
SELECT DATEADD(MILLISECOND,DATEDIFF(MILLISECOND,#DiffMSTime,#DateValue),0)
END
PS: I know the last one has overflow!!
Is there any more efficient way to do that?!
With conversions and transformations it always depends on lots of factors.
Best way: Build a test rig and set aside a few minutes or better hours.
The test rig creates numbers from 0 to 9 999 999 - about 10 million rows. Kudos to Jeff Moden for the SQL spackle that creates the number list.
DROP TABLE IF EXISTS #numbers
;
DROP TABLE IF EXISTS #dates
;
CREATE TABLE
#numbers
(
number integer NOT NULL
)
;
CREATE TABLE
#dates
(
dated datetime2(7) NOT NULL
)
;
WITH
cteNum
(
smallnum
)
AS
(
SELECT Cast( 1 AS integer )
UNION ALL
SELECT Cast( 2 AS integer )
UNION ALL
SELECT Cast( 3 AS integer )
UNION ALL
SELECT Cast( 4 AS integer )
UNION ALL
SELECT Cast( 5 AS integer )
UNION ALL
SELECT Cast( 6 AS integer )
UNION ALL
SELECT Cast( 7 AS integer )
UNION ALL
SELECT Cast( 8 AS integer )
UNION ALL
SELECT Cast( 9 AS integer )
UNION ALL
SELECT Cast( 0 AS integer )
)
INSERT INTO
#numbers
(
number
)
SELECT
num1.smallnum * 1000000 + num2.smallnum * 100000 + num3.smallnum * 10000 + num4.smallnum * 1000
+ num5.smallnum * 100 + num6.smallnum * 10 + num7.smallnum
FROM
cteNum AS num1
CROSS JOIN cteNum AS num2
CROSS JOIN cteNum AS num3
CROSS JOIN cteNum AS num4
CROSS JOIN cteNum AS num5
CROSS JOIN cteNum AS num6
CROSS JOIN cteNum AS num7
;
INSERT INTO
#dates
(
dated
)
SELECT
Cast( DateAdd( ms, nums.number, dated.basedate) AS datetime2(7) ) AS dated
FROM
#numbers AS nums
CROSS JOIN
(
SELECT Cast(GetDate() AS datetime2(7) ) AS basedate
) dated
;
DROP TABLE IF EXISTS #numbers
;
This will take from a couple of seconds to a couple of minutes to create.
Using a table minimises the amount of effort to table maintenance done by the query analyzer.
The test of conversion times can then be done in a controlled environment. Tip: Using a start and end time capture eliminates the overhead for a SQL trace.
SET NOCOUNT ON
;
DECLARE
#datetimestarted datetime2(7),
#datetimeended datetime2(7),
#result varchar(200),
#crlf char(2) = char(13) + char(10)
;
SET #datetimestarted = Getdate()
;
SELECT
dated,
datedrounded = Cast( dated AS datetime2(0) )
FROM
#dates
;
SET #datetimeended = Getdate()
;
SET #result = 'Processing time = ' + Cast( Datediff( ms, #datetimestarted, #datetimeended ) / 1000 AS varchar(12) ) + ' seconds' + #crlf
+ ' > Start time: ' + Convert( varchar(20), #datetimestarted, 126 ) + #crlf
+ ' > End time: ' + Convert( varchar(20), #datetimeended, 126 ) + #crlf
;
PRINT #result
;
SET #datetimestarted = Getdate()
;
SELECT
dated,
datedrounded = Convert( datetime2(0), dated )
FROM
#dates
;
SET #datetimeended = Getdate()
;
SET #result = 'Processing time = ' + Cast( Datediff( ms, #datetimestarted, #datetimeended ) / 1000 AS varchar(12) ) + ' seconds' + #crlf
+ ' > Start time: ' + Convert( varchar(20), #datetimestarted, 126 ) + #crlf
+ ' > End time: ' + Convert( varchar(20), #datetimeended, 126 ) + #crlf
;
PRINT #result
;
Run time on my VM is about 3 minutes for each option with Cast taking a tad bit longer than Convert. Now this depends on what one wants to achieve so feel free to change the transformations as required.
And finally the clean up.
DROP TABLE IF EXISTS #dates
;
Final tip: date and datetime are kind of obsolete datetime types in SQL Server. Calculation with these is actually easier than the new datetime2 type allowing mathematical calculations.
datetime2 requires the Dateadd function use.
However datetime2 is easier to convert to current database interactions between different types of RDBMS. Also easier to work in standard ISO 8601 formats which makes transferring data between different parts of the world a whole lot easier.
Facing an issue with T-sql Datediff function,
I am calculating date difference in minutes between two dates, and then in hours.
Minute is giving me correct result
SELECT DATEDIFF(minute,'2018-01-22 23:59:00.000','2018-01-23 00:44:00.000')
Result 45 minutes
But when I am trying to calculate hours it's giving me incorrect results for days that are almost over and new day begins,
So if the time parameter is '23:59:00' and the second parameter is '00:44:00' it returns 1 hour difference when its only 45 minutes.
SELECT DATEDIFF(HOUR,'2018-01-22 23:59:00.000','2018-01-23 00:44:00.000')
Result 1 Hour --Incorrect
I am expecting this result to be zero
SELECT DATEDIFF(HOUR,'2018-01-22 23:59:00.000','2018-01-23 00:44:00.000')
Result 0 Hour -- This is the result expected
Update:
Posting my Function here if anyone needs to Calculate difference between two dates in format as Day:Hour:Minute
ALTER FUNCTION [dbo].[UDF_Fedex_CalculateDeliveryOverdue]
(
-- Add the parameters for the function here
#requiredDate VARCHAR(50),
#deliveryStamp VARCHAR(50)
)
RETURNS VARCHAR(25)
AS
BEGIN
DECLARE #ResultVar VARCHAR(25)
SET #ResultVar = ( SELECT CASE WHEN a.Days = 0 AND a.Hours = 0 THEN CAST(a.Minutes AS VARCHAR(10)) + ' Minutes'
WHEN a.Days = 0 THEN CAST(a.Hours AS VARCHAR(10)) + ' Hours ' + CAST(a.Minutes AS VARCHAR(10)) + ' Minutes'
ELSE CAST(a.Days AS VARCHAR(10)) +' Day ' + CAST(a.Hours AS VARCHAR(10)) +' Hours ' + CAST(a.Minutes AS VARCHAR(10)) + ' Minutes'
END
FROM ( SELECT DATEDIFF(hh, #requiredDate,#deliveryStamp)/24 AS 'Days'
,(DATEDIFF(MI, #requiredDate,#deliveryStamp)/60) -
(DATEDIFF(hh, #requiredDate,#deliveryStamp)/24)*24 AS 'Hours'
,DATEDIFF(mi, #requiredDate,#deliveryStamp) -
(DATEDIFF(mi, #requiredDate,#deliveryStamp)/60)*60 AS 'Minutes'
) a)
-- Return the result of the function
RETURN #ResultVar
END
To get value 0 you need to get the result in minutes, and convert to hours:
SELECT DATEDIFF(minute,'2018-01-22 23:59:00.000','2018-01-23 00:44:00.000')/60
For more precision:
SELECT DATEDIFF(minute,'2018-01-22 23:59:00.000','2018-01-23 00:44:00.000')/60.0
Good Day
I am working of a existing SQL Server Database. What the developers did is to keep the Date and time separate. The Date is in DateTime format (what I want) but the time is incorrect. if it is 14:30 it shows as 1430 when its 09:25 shows as 925. I am trying tyo combine the date and time to have a Date Time view for an program I am writing on top of this database.
I have created the date as a normal date like this:
CASE
WHEN LEN(T0.BeginTime) = 3 THEN '0' + LEFT(T0.BeginTime, 1) + ':' + RIGHT(T0.BeginTime, 2)
ELSE LEFT(T0.BeginTime, 2) + ':' + RIGHT(T0.BeginTime, 2)
END AS 'NEW Start Time'`
The date now looks like it's the correct format but when I want to combine the date and time I get VARCHAR to DateTime error.
How can I fix this?
This is the error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value (ONLY RAN 804 RECORDS)
Thanks
This should do the trick, Hope it helps.
DECLARE #DateTime TABLE (
DateWithTime DATE,
BeginTime INT);
INSERT INTO #DateTime
VALUES ('2014-08-04', '1525'),
('2014-08-04', '525'),
('2014-08-04', '15'),
('2014-08-04', '5'),
('2014-08-04', '0'),
('2014-08-04', '90')
;WITH cte_BeginTimeFix
AS (
SELECT
CONVERT(VARCHAR(10), DateWithTime, 120) AS DateWithTime,
RIGHT('0000' + CAST(BeginTime AS VARCHAR(4)), 4) AS BeginTime
FROM #DateTime
)
, cte_DateString
AS (
SELECT DateWithTime,
BeginTime,
DateWithTime + ' ' + STUFF(STUFF('00:00:00.000', 4, 2, RIGHT(BeginTime, 2)), 1, 2, LEFT(BeginTime, 2)) AS DateTimeStr
FROM cte_BeginTimeFix
)
SELECT DateWithTime,
BeginTime,
CASE
WHEN ISDATE(DateTimeStr) = 1 THEN CAST(DateTimeStr AS DATETIME)
ELSE NULL
END AS DateTimeStr
FROM cte_DateString
A different approach is to convert the time column in minutes and add it to the date
DATEADD(minute, T0.BeginTime / 100 * 60 + T0.BeginTime % 100
, CONVERT(VARCHAR, T0.BeginDate, 112))
with that the length of the time column doesn't matter
This should work:
CONVERT
(
DATETIME,
CONVERT(VARCHAR,T0.Date,112) +
' ' +
CASE
WHEN ISNULL(T0.BeginTime,'0') = '0'
THEN '00:00'
ELSE
RIGHT
(
'00' + LEFT(T0.BeginTime,LEN(T0.BeginTime) - 3),
2
) +
':' +
RIGHT(T0.BeginTime,2)
END
)
I wrote a SQL function to convert a datetime value in SQL to a friendlier "n Hours Ago" or "n Days Ago" etc type of message. And I was wondering if there was a better way to do it.
(Yes I know "don't do it in SQL" but for design reasons I have to do it this way).
Here is the function I've written:
CREATE FUNCTION dbo.GetFriendlyDateTimeValue
(
#CompareDate DateTime
)
RETURNS nvarchar(48)
AS
BEGIN
DECLARE #Now DateTime
DECLARE #Hours int
DECLARE #Suff nvarchar(256)
DECLARE #Found bit
SET #Found = 0
SET #Now = getDate()
SET #Hours = DATEDIFF(MI, #CompareDate, #Now)/60
IF #Hours <= 1
BEGIN
SET #Suff = 'Just Now'
SET #Found = 1
RETURN #Suff
END
IF #Hours < 24
BEGIN
SET #Suff = ' Hours Ago'
SET #Found = 1
END
IF #Hours >= 8760 AND #Found = 0
BEGIN
SET #Hours = #Hours / 8760
SET #Suff = ' Years Ago'
SET #Found = 1
END
IF #Hours >= 720 AND #Found = 0
BEGIN
SET #Hours = #Hours / 720
SET #Suff = ' Months Ago'
SET #Found = 1
END
IF #Hours >= 168 AND #Found = 0
BEGIN
SET #Hours = #Hours / 168
SET #Suff = ' Weeks Ago'
SET #Found = 1
END
IF #Hours >= 24 AND #Found = 0
BEGIN
SET #Hours = #Hours / 24
SET #Suff = ' Days Ago'
SET #Found = 1
END
RETURN Convert(nvarchar, #Hours) + #Suff
END
As you say, I probably wouldn't do it in SQL, but as a thought exercise have a MySQL implementation:
CASE
WHEN compare_date between date_sub(now(), INTERVAL 60 minute) and now()
THEN concat(minute(TIMEDIFF(now(), compare_date)), ' minutes ago')
WHEN datediff(now(), compare_date) = 1
THEN 'Yesterday'
WHEN compare_date between date_sub(now(), INTERVAL 24 hour) and now()
THEN concat(hour(TIMEDIFF(NOW(), compare_date)), ' hours ago')
ELSE concat(datediff(now(), compare_date),' days ago')
END
Based on a similar sample seen on the MySQL Date and Time manual pages
In Oracle:
select
CC.MOD_DATETIME,
'Last modified ' ||
case when (sysdate - cc.mod_datetime) < 1
then round((sysdate - CC.MOD_DATETIME)*24) || ' hours ago'
when (sysdate - CC.MOD_DATETIME) between 1 and 7
then round(sysdate-CC.MOD_DATETIME) || ' days ago'
when (sysdate - CC.MOD_DATETIME) between 8 and 365
then round((sysdate - CC.MOD_DATETIME) / 7) || ' weeks ago'
when (sysdate - CC.MOD_DATETIME) > 365
then round((sysdate - CC.MOD_DATETIME) / 365) || ' years ago'
end
from
customer_catalog CC
My attempt - this is for MS SQL. It supports 'ago' and 'from now', pluralization and it doesn't use rounding or datediff, but truncation -- datediff gives 1 month diff between 8/30 and 9/1 which is probably not what you want. Rounding gives 1 month diff between 9/1 and 9/16. Again, probably not what you want.
CREATE FUNCTION dbo.GetFriendlyDateTimeValue( #CompareDate DATETIME ) RETURNS NVARCHAR(48) AS BEGIN
declare #s nvarchar(48)
set #s='Now'
select top 1 #s=convert(nvarchar,abs(n))+' '+s+case when abs(n)>1 then 's' else '' end+case when n>0 then ' ago' else ' from now' end from (
select convert(int,(convert(float,(getdate()-#comparedate))*n)) as n, s from (
select 1/365 as n, 'Year' as s union all
select 1/30, 'Month' union all
select 1, 'Day' union all
select 7, 'Week' union all
select 24, 'Hour' union all
select 24*60, 'Minute' union all
select 24*60*60, 'Second'
) k
) j where abs(n)>0 order by abs(n)
return #s
END
Your code looks functional. As for a better way, that is going to get subjective. You might want to check out this page as it deals with time spans in SQL.
How about this? You could expand this pattern to do "years" messages, and you could put in a check for "1 day" or "1 hour" so it wouldn't say "1 days ago"...
I like the CASE statement in SQL.
drop function dbo.time_diff_message
GO
create function dbo.time_diff_message (
#input_date datetime
)
returns varchar(200)
as
begin
declare #msg varchar(200)
declare #hourdiff int
set #hourdiff = datediff(hour, #input_date, getdate())
set #msg = case when #hourdiff < 0 then ' from now' else ' ago' end
set #hourdiff = abs(#hourdiff)
set #msg = case when #hourdiff > 24 then convert(varchar, #hourdiff/24) + ' days' + #msg
else convert(varchar, #hourdiff) + ' hours' + #msg
end
return #msg
end
GO
select dbo.time_diff_message('Dec 7 1941')
Thanks for the various code posted above.
As Hafthor pointed out there are limitations of the original code to do with rounding. I also found that some of the results his code kicked out didn't match with what I'd expect e.g. Friday afternoon -> Monday morning would show as '2 days ago'. I think we'd all call that 3 days ago, even though 3 complete 24 hour periods haven't elapsed.
So I've amended the code (this is MS SQL). Disclaimer: I am a novice TSQL coder so this is quite hacky, but works!!
I've done some overrides - e.g. anything up to 2 weeks is expressed in days. Anything over that up to 2 months is expressed in weeks. Anything over that is in months etc. Just seemed like the intuitive way to express it.
CREATE FUNCTION [dbo].[GetFriendlyDateTimeValue]( #CompareDate DATETIME ) RETURNS NVARCHAR(48) AS BEGIN
declare #s nvarchar(48)
set #s='Now'
select top 1 #s=convert(nvarchar,abs(n))+' '+s+case when abs(n)>1 then 's' else '' end+case when n>0 then ' ago' else ' from now' end from (
select convert(int,(convert(float,(getdate()-#comparedate))*n)) as n, s from (
select 1/365 as n, 'year' as s union all
select 1/30, 'month' union all
select 1/7, 'week' union all
select 1, 'day' union all
select 24, 'hour' union all
select 24*60, 'minute' union all
select 24*60*60, 'second'
) k
) j where abs(n)>0 order by abs(n)
if #s like '%days%'
BEGIN
-- if over 2 months ago then express in months
IF convert(nvarchar,DATEDIFF(MM, #CompareDate, GETDATE())) >= 2
BEGIN
select #s = convert(nvarchar,DATEDIFF(MM, #CompareDate, GETDATE())) + ' months ago'
END
-- if over 2 weeks ago then express in weeks, otherwise express as days
ELSE IF convert(nvarchar,DATEDIFF(DD, #CompareDate, GETDATE())) >= 14
BEGIN
select #s = convert(nvarchar,DATEDIFF(WK, #CompareDate, GETDATE())) + ' weeks ago'
END
ELSE
select #s = convert(nvarchar,DATEDIFF(DD, #CompareDate, GETDATE())) + ' days ago'
END
return #s
END
The posts above gave me some good ideas so here is another function for anyone using SQL Server 2012.
CREATE FUNCTION [dbo].[FN_TIME_ELAPSED]
(
#TIMESTAMP DATETIME
)
RETURNS VARCHAR(50)
AS
BEGIN
RETURN
(
SELECT TIME_ELAPSED =
CASE
WHEN #TIMESTAMP IS NULL THEN NULL
WHEN MINUTES_AGO < 60 THEN CONCAT(MINUTES_AGO, ' minutes ago')
WHEN HOURS_AGO < 24 THEN CONCAT(HOURS_AGO, ' hours ago')
WHEN DAYS_AGO < 365 THEN CONCAT(DAYS_AGO, ' days ago')
ELSE CONCAT(YEARS_AGO, ' years ago') END
FROM ( SELECT MINUTES_AGO = DATEDIFF(MINUTE, #TIMESTAMP, GETDATE()) ) TIMESPAN_MIN
CROSS APPLY ( SELECT HOURS_AGO = DATEDIFF(HOUR, #TIMESTAMP, GETDATE()) ) TIMESPAN_HOUR
CROSS APPLY ( SELECT DAYS_AGO = DATEDIFF(DAY, #TIMESTAMP, GETDATE()) ) TIMESPAN_DAY
CROSS APPLY ( SELECT YEARS_AGO = DATEDIFF(YEAR, #TIMESTAMP, GETDATE()) ) TIMESPAN_YEAR
)
END
GO
And the implementation:
SELECT TIME_ELAPSED = DBO.FN_TIME_ELAPSED(AUDIT_TIMESTAMP)
FROM SOME_AUDIT_TABLE
CASE WHEN datediff(SECOND,OM.OrderDate,GETDATE()) < 60 THEN
CONVERT(NVARCHAR(MAX),datediff(SECOND,OM.OrderDate,GETDATE())) +' seconds ago'
WHEN datediff(MINUTE,OM.OrderDate,GETDATE()) < 60 THEN
CONVERT(NVARCHAR(MAX),datediff(MINUTE,OM.OrderDate,GETDATE())) +' minutes ago'
WHEN datediff(HOUR,OM.OrderDate,GETDATE()) < 24 THEN
CONVERT(NVARCHAR(MAX),datediff(HOUR,OM.OrderDate,GETDATE())) +' hours ago'
WHEN datediff(DAY,OM.OrderDate,GETDATE()) < 8 THEN
CONVERT(NVARCHAR(MAX),datediff(DAY,OM.OrderDate,GETDATE())) +' Days ago'
ELSE FORMAT(OM.OrderDate,'dd/MM/yyyy hh:mm tt') END AS TimeStamp