DateTime to time interval in T-Sql - sql

I am working on an SSRS report and I need to display hourly data count in a table.
The hourly interval need to be displayed as 4:00pm - 5:00pm
I have a log table which has DateTime available with each transaction. This table refreshes daily.
I am grouping on the hour component of this timestamp to get the hourly count.
Is there any option available in SQL/SSRS for converting hourly value to 04:00pm- 05:00pm format?

I would recommend that you simply create a simple scalar function in SQL Server for this one. See following example:
CREATE FUNCTION DateTimeToHourInterval
(
#currentDateTime DATETIME
)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #nextHourDateTime DATETIME = DATEADD(HOUR, 1, #currentDateTime);
DECLARE #intervalStart VARCHAR(10) = REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR(50), DATEADD(MINUTE, -1* DATEPART(MINUTE, #currentDateTime), #currentDateTime), 100), 7)), 'PM', ' PM'), 'AM', ' AM');
DECLARE #intervalEnd VARCHAR(10) = REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR(50), DATEADD(MINUTE, -1* DATEPART(MINUTE, #nextHourDateTime), #nextHourDateTime), 100), 7)), 'PM', ' PM'), 'AM', ' AM');
RETURN #intervalStart + ' - ' + #intervalEnd
END
The function can now be used as follow:
SELECT dbo.DateTimeToHourInterval(GETDATE());

Use case statement:
SELECT CASE
WHEN DATEPART(hour,TransactionDateTime) = 0 THEN '12:00am-01:00am'
WHEN DATEPART(hour,TransactionDateTime) = 1 THEN '01:00am-02:00am' ...
END FROM your_table
Dynamic way:
SELECT CASE
WHEN DATEPART(hour,TransactionDateTime) >12 THEN cast (DATEPART(hour,TransactionDateTime) -12 as VARCHAR (2)) + ':00pm-' +cast(DATEPART(hour,TransactionDateTime) -11 as VARCHAR (2)) + ':00pm'
WHEN DATEPART(hour,TransactionDateTime) <12
cast (DATEPART(hour,TransactionDateTime) as VARCHAR (2)) + ':00am-' +cast(DATEPART(hour,TransactionDateTime)+1 as VARCHAR (2)) + ':00am'
WHEN DATEPART(hour,TransactionDateTime) =12
cast (DATEPART(hour,TransactionDateTime) as VARCHAR (2)) +':00pm-1:00pm'
END
FROM your_table
For corner case (11pm) handle am/pm using a nested case statement. check the datepart and return am/pm based on the results. I was not able to test the query since I am posting this from my smartphone.
Hope this helps

Use the below script to convert datetime to 12 hour format.
SELECT LEFT (STUFF(RIGHT('0'+LTRIM(RIGHT(CONVERT(varchar,YourColumn,100),7)),7),6,0,''),2)+':00'+RIGHT (LTRIM(RIGHT(CONVERT(VARCHAR(20), YourColumn, 100), 7)),2)
+' - '+LEFT (STUFF(RIGHT('0'+LTRIM(RIGHT(CONVERT(varchar, DATEADD(hh, 1, YourColumn),100),7)),7),6,0,''),2)+':00'+RIGHT (LTRIM(RIGHT(CONVERT(VARCHAR(20), DATEADD(hh, 1, YourColumn), 100), 7)),2)
FROM YourTable
Sample output :

Related

SQL Column Concatenation whilst keeping the datatype of first column [duplicate]

In an extract I am dealing with, I have 2 datetime columns. One column stores the dates and another the times as shown.
How can I query the table to combine these two fields into 1 column of type datetime?
Dates
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
Times
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
You can simply add the two.
if the Time part of your Date column is always zero
and the Date part of your Time column is also always zero (base date: January 1, 1900)
Adding them returns the correct result.
SELECT Combined = MyDate + MyTime FROM MyTable
Rationale (kudos to ErikE/dnolan)
It works like this due to the way the date is stored as two 4-byte
Integers with the left 4-bytes being the date and the right
4-bytes being the time. Its like doing $0001 0000 + $0000 0001 =
$0001 0001
Edit regarding new SQL Server 2008 types
Date and Time are types introduced in SQL Server 2008. If you insist on adding, you can use Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 regarding loss of precision in SQL Server 2008 and up (kudos to Martin Smith)
Have a look at How to combine date and time to datetime2 in SQL Server? to prevent loss of precision using SQL Server 2008 and up.
If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
This is an alternative solution without any char conversions:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
You will only get milliseconds accuracy this way, but that would normally be OK. I have tested this in SQL Server 2008.
This worked for me
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(on SQL 2008 R2)
If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:
DECLARE #DateOnly AS datetime
DECLARE #TimeOnly AS datetime
SET #DateOnly = '07 aug 2009 00:00:00'
SET #TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
as datetime)
It's rough and ready, but it works!
If both of your fields are datetime then simply adding those will work.
eg:
Declare #d datetime, #t datetime
set #d = '2009-03-12 00:00:00.000';
set #t = '1899-12-30 12:30:00.000';
select #d + #t
If you used Date & Time datatype then just cast the time to datetime
eg:
Declare #d date, #t time
set #d = '2009-03-12';
set #t = '12:30:00.000';
select #d + cast(#t as datetime)
This was my solution which ignores the date value of the time column
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
Hope this helps others
Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
Convert both field into DATETIME :
SELECT CAST(#DateField as DATETIME) + CAST(#TimeField AS DATETIME)
and if you're using Getdate() use this first:
DECLARE #FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(#FechaActual as DATETIME) + CAST(#HoraInicioTurno AS DATETIME)
I had many errors as stated above so I did it like this
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
It worked for me.
Finding this works for two dates where you want time from one and date from the other:
declare #Time as datetime = '2021-11-19 12:34'
declare #Date as datetime = '2021-10-10'
SELECT #time + datediff(day, #Time, #Date)
DECLARE #Dates table ([Date] datetime);
DECLARE #Times table ([Time] datetime);
INSERT INTO #Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM #Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM #Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
Prints:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
To combine date from a datetime column and time from another datetime column this is the best fastest solution for you:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
SELECT CAST(CAST(#DateField As Date) As DateTime) + CAST(CAST(#TimeField As Time) As DateTime)
Another way is to use CONCATand CAST, be aware, that you need to use DATETIME2(x) to make it work. You can set x to anything between 0-7 7 meaning no precision loss.
DECLARE #date date = '2018-03-12'
DECLARE #time time = '07:00:00.0000000'
SELECT CAST(CONCAT(#date, ' ', #time) AS DATETIME2(7))
Returns 2018-03-12 07:00:00.0000000
Tested on SQL Server 14
simply concatenate both , but cast them first as below
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between #FromDate and #ToDate
The existing answers do not address the datetime2 datatype so I will add mine:
Assuming that you want to add a time value to a datetime2 value where:
The datetime2 value could contain non-zero time component and/or fractional seconds
The time value could contain the value 23:59:59.9999999 which is 86,399.9999999 seconds, 86,399,999,999.9 microseconds or 86,399,999,999,900 nanoseconds¹
Due to the limitations of dateadd function¹ you must add them in two steps:
Convert the time value to seconds and use dateadd(second, ...)
Extract the nanoseconds from the time value and use dateadd(nanosecond, ...) to add them to the date calculated above
declare #dv datetime2 = '2000-01-01 12:34:56.7890123';
declare #tv time = '23:59:59.9999999';
select dateadd(
nanosecond,
datepart(nanosecond, #tv),
dateadd(
second,
datepart(hour, #tv) * 60 * 60 + datepart(minute, #tv) * 60 + datepart(second, #tv),
#dv
)
);
-- 2000-01-02 12:34:56.7890122
¹ Nanosecond values might not fit in int datatype which dateadd function expects.
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
Works like a charm
I ran into similar situation where I had to merge Date and Time fields to DateTime field. None of the above mentioned solution work, specially adding two fields as the data type for addition of these 2 fields is not same.
I created below solution, where I added hour and then minute part to the date. This worked beautifully for me. Please check it out and do let me know if you get into any issues.
;with tbl
as
(
select StatusTime = '12/30/1899 5:17:00 PM', StatusDate = '7/24/2019 12:00:00 AM'
)
select DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME)))
from tbl
Result: 2019-07-24 17:17:00.000

SQL Date/Time Format

How to convert date/time from 20150323153528 to 2015-03-23 15:35:28.000. I need this to filter based on the getdate(). Thanks in advance.
Select * from table
Where 20150323153528 > GETDATE() - 7
Statement to convert date to your requirement
DECLARE #Date varchar(20) = '20150323153528'
Select * from table Where
CONVERT(DATETIME, CONVERT(CHAR(8), #Date), 121) + ' ' + stuff(stuff(right('000000' + cast(#Date as varchar),6),5,0,':'),3,0,':') as DATETIME > GETDATE() - 7
In MS SQL you could use
DECLARE #Date varchar(20) = '20150323153528'
Select * from table Where CAST(convert(varchar,#Date) as datetime) > GETDATE() - 7
Please read this page.
SELECT convert(varchar, getdate(), 120) — yyyy-mm-dd hh:mm:ss(24h)
Note: I assume this is a Microsoft SQL Server environment using T-SQL:
The formatting of date / datetime values is not a concern of T-SQL. You should do that in your presentation-layer (i.e. your frontend code).
If you have date/time values represented as integers of the form 20150323153528 then you cannot use them in T-SQL. You need to convert them to strings (preferably in ISO-8601 format) for SQL Server to successfully internally convert them to datetime (or datetimeoffset) values which can then be compared with other datetime values.
I suggest performing the conversion in your application code before you send it to SQL, as a datetime-typed parameter value, like so:
Int32 weirdDateValue = 20150323153528;
String s = weirdDateValue.ToString( CultureInfo.InvariantCulture );
String dtValueAsIso8601 = String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
s.Substring(0, 4), s.Substring(4, 2), s.Substring(6, 2),
s.Substring(8, 2), s.Substring(10, 2), s.Substring(12, 2), s.Substring(14)
);
DateTime dtValue = DateTime.ParseExact( dtValueAsIso8601, "yyyy-MM-dd HH:mm:ss.fff" );
cmd.Parameters.Add("#dtValue", SqlDbType.DateTime).Value = dtValue;
In T-SQL the process is pretty much the same, except using MID - note that MID uses 1-based character indexes instead of 0-based:
DECLARE #input int = 20150323153528
DECLARE #s varchar( 14 ) = CONVERT( #input, nvarchar(14) )
DECLARE #dtStr varchar( 24 ) = MID( #s, 1, 2 ) + '-' + MID( #s, 3, 2 ) + '-' + MID( #s, 5, 2 ) + ' ' + -- etc...
DECLARE #dt datetime = CONVERT( #dtStr, datetime )
SELECT
*
FROM
[table]
WHERE
#dt > GETDATE() - 7
If the integer values are stored in an actual column instead of a parameter you'll need to convert the logic into a scalar UDF which performs the conversion. I strongly suggest you change the table's design to add a strongly-typed datetime column and permanently store the value there, and then drop the datetime-as-int column:
CREATE FUNCTION ConvertIntDateIntoDateTime(#dateAsInt int) RETURNS datetime AS
BEGIN
-- same code as above minus the SELECT statement
RETURN #dt
END
Used in an inner subquery to allow the data to be accessed in WHERE statements, like so:
SELECT
*
FROM
(
SELECT
*,
dbo.ConvertIntDateIntoDateTime( someDateColumn ) AS someDateColumn2
FROM
[table]
) AS FixedTable
WHERE
FixedTable.someDateColumn2 > GETDATE() - 7

CAST Correct VARCHAR to DateTime

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
)

Convert DateTime with NULL value

I am running this query
select * from dbo.CHARGES m
LEFT JOIN Docs z ON z.DocId=m.DocId
AND CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
And getting Conversion failed when converting date and/or time from character string, since some rows of DocDate, DocTime have null value
Here DocTime is Varchar(5)
How can i run this query by ignoring NULL or wrong values?
If your strings are in the format yyyy-MM-dd hh:mm then your convert expression will be something like:
SELECT CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01') + ' ' + ISNULL(DocTime, '00:00'), 121)
However, it is probably adivisable to check that it actually is a date before you try to convert it:
SET DATEFORMAT YMD;
SELECT DocDate,
DocTime,
Formatted = CASE WHEN ISDATE(ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00')) = 1
THEN CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00'), 121)
ELSE NULL
END
FROM (VALUES
('2013-10-01', '17:30'),-- CORRECT FORMAT
('2013-10-01', NULL), -- NULL TIME
('2013-13-10', '17:30'), -- INVALID DATE
('2013-01-05', 'XX:30'), -- INVALID TIME
(NULL, '17:00') -- NULL DATE
) t (DocDate, DocTime);
Note, I have set the dateformat even though it is set within the convert, this is for the benefit of ISDATE(), if the date format is not set this way, it may think that 2013-13-10 is a valid date (13th October 2013), but will through an error when it comes to the convert.
If/When you upgrade to SQL-Server 2012 you can simply use TRY_CONVERT:
SET DATEFORMAT YMD;
SELECT DocDate,
DocTime,
Formatted = TRY_CONVERT(DATETIME, ISNULL(DocDate, '1900-01-01')
+ ' ' + ISNULL(DocTime, '00:00'), 121)
FROM (VALUES
('2013-10-01', '17:30'),-- CORRECT FORMAT
('2013-10-01', NULL), -- NULL TIME
('2013-13-10', '17:30'), -- INVALID DATE
('2013-01-05', 'XX:30'), -- INVALID TIME
(NULL, '17:00') -- NULL DATE
) t (DocDate, DocTime);
Examples on SQL Fiddle
I don't condone this approach, and (as I have in a comment) would strongly advise correcting the problem (which is storing data as the wrong type) rather than jumping through hoops to work around data errors.
Try this code, the query depend of your necessity.
With Null Values
select * from dbo.CHARGES m
LEFT JOIN Docs z
ON z.DocId=m.DocId
AND (
z.DocDate IS NULL
OR z.DocTime IS NULL
OR CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
)
Without Null Values
select * from dbo.CHARGES m
LEFT JOIN Docs z
ON z.DocId=m.DocId
AND (
NOT z.DocDate IS NULL
AND NOT z.DocTime IS NULL
AND CHARGE_DATE=CAST(z.DocDate + z.DocTime AS DATETIME)
)

combine 2 varchar column's data and convert to datetime

I have 2 columns in a table of varchar datatype.
date and type are the column names in table.
the data present in the table looks like this
date time
20090610 132713
20090610 132734
i need ms sql server query to concatenate these 2 columns data and display as datetime format.
Note :
1. the datatype of those 2 columns cannot be changed now.
2. i tried
select convert(datetime,date + time)
it says "Conversion failed when converting date and/or time from character string."
Suggest the possible solution.
This will return a datetime. The bottom line is to be replaced by your table
select convert(datetime,date,112)+
coalesce(stuff(stuff(rtrim(time), 5,0,':'), 3,0,':'), '') newdate
from
(VALUES ('20090610','132713'),('20090610', '132734'),('20090610', ' ')) yourtable(date,time)
Result:
newdate
2009-06-10 13:27:13.000
2009-06-10 13:27:34.000
2009-06-10 00:00:00.000
You can get it using
SELECT
convert(varchar, convert(datetime, date), 111)
+ ' ' + substring(time, 1, 2)
+ ':' + substring(time, 3, 2)
+ ':' + substring(time, 5, 2)
CREATE TABLE #Table
(
[date] VARCHAR(100),
[time] VARCHAR(100)
)
INSERT INTO #Table VALUES
('20090610','132713'),
('20090610','132734')
;WITH Bits_CTE
AS
(
SELECT
[Date],
[Time],
[hrs] = CONVERT(INT,SUBSTRING([Time], 1, 2)),
[mns] = CONVERT(INT,SUBSTRING([Time], 3, 2)),
[secs] = CONVERT(INT,SUBSTRING([Time], 5, 2))
FROM #Table
)
SELECT
[Date],
[Time],
DATEADD(HOUR,[hrs],
DATEADD(MINUTE,[mns],
DATEADD(SECOND,[secs],[Date])))
FROM Bits_CTE
CREATE FUNCTION [dbo].[DateTimeAdd]
(
#datepart date,
#timepart time
)
RETURNS datetime2
AS
BEGIN
RETURN DATEADD(dd, DATEDIFF(dd, 0, #datepart), CAST(#timepart AS datetime2));
END
Sorry - Missed the bit in your question about storing the date and time as varchars. You would therefore still need to convert these data itemsbefore using this function.