Adding two time fields together - sql-server

I have two columns within my table they are set as nvarchar fields but contain time values.
one column is a time field one is the duration field
eg.
Time 1 = 15:05:22 (time field)
Time 2 = 00:02:00 (duration field)
I want to output Time 1 + Time 2 = 15:07:22
I have tried CAST(time1 as datetime)+CAST(time2 as datetime)
but I get 1900-01-01 15:07:22.000, and I don't want the date part. I can't use cast as time as I get an error I presume this is because the fields are set as nvarchar and not date/time?

Just cast the result to time to get rid of the date portion:
DECLARE #time_txt varchar(8);
DECLARE #duration_txt varchar(8);
SET #time_txt = '15:05:22';
SET #duration_txt = '00:02:00';
SELECT CAST(CAST(#time_txt as datetime) + CAST(#duration_txt as datetime) as time);
-- yields the time value 15:07:22.0000000
If you need this as a string (for example, in hh:mm:ss format), you can use CONVERT with the appropriate format option:
...
SELECT CONVERT(varchar(8), CAST(#time_txt as datetime) + CAST(#duration_txt as datetime), 108);
-- yields the string 15:07:22
PS: In general, you should use time columns for time values instead of varchar columns. Unfortunately, SQL Server does not have a really good data type for durations (time spans).

select dateadd(second,datediff(second,0,time1),time2) as Time3
from your_table

Related

Update Only TZoffset in DATETIME column

I have a set of dates like 2023-11-30 23:59:59.0000000 +00:00. I want to update only the time zone offset from +00:00 to +01:00 to all of them.
If it makes things easier, all of the times are 23:59:59.0000000 and only the date differentiates.
I've tried this:
UPDATE Table SET Date = DATEADD(DAY, DATEDIFF(DAY, 0, Date), '2023-11-30 23:59:59.0000000 +01:00')
But it only worked with accuracy up to seconds, without milliseconds, nanoseconds and tzoffset. I've got this error, when I tried that:
Conversion failed when converting date and/or time from character string.
Seems like you want TODATETIMEOFFSET:
DECLARE #YourValue datetimeoffset(7) = '2023-11-30 23:59:59.0000000 +00:00';
SELECT TODATETIMEOFFSET(#YourValue,'+01:00');
This returns 2023-11-30 23:59:59.0000000 +01:00. This works because it takes your datetimeoffset value and (implicitly) converts it to a datetime2 first, which truncates the offset value, and then adds the new offset to the value; thus not changing the actual time and just the offset.
If you're saying that you actually change the value so that the date and time changes with the offset, then you want SWITCHOFFSET:
DECLARE #YourValue datetimeoffset(7) = '2023-11-30 23:59:59.0000000 +00:00';
SELECT SWITCHOFFSET(#YourValue,'+01:00');
This returns 2023-12-01 00:59:59.0000000 +01:00.

How to get a time difference between two time columns for SSRS

I have two tables I am trying to get a difference from in SQL. Table A has a time in the following format: 07:40:06,
08:33:34,
13:42:09,
Table B is in the same format. I want to return in an actual time for example 7:40:00 in A and 7:50:00 in B result in new column 00:10:00.
Thanks,
I admit that this is sort of cheesy, but appears to work. You could use a constant date, and add the times to that as strings. Then subtract and format however you like. For example: HH:mm:ss. This will give the result of 00:10:00
DECLARE #contstantDate DATETIME = DATEFROMPARTS(1900,1,1)
DECLARE #date1 DATETIME = #contstantDate + '7:40:00'
DECLARE #date2 DATETIME = #contstantDate + '7:50:00'
SELECT FORMAT(#date2-#date1, 'HH:mm:ss')

Dividing a date value in T-SQL

I am working on migrating an Access program into SQL Server.
The following is my SQL code taken directly from access.
(([Promise Date])-([Date Recieved]))/100
As you can see, I am attempting to do a division on a datetime value.
This is the error message i receive:
Msg 257, Level 16, State 3, Line 1
Implicit conversion from data type datetime to int is not allowed. Use the
CONVERT function to run this query.
Both fields are type Datetime. Any ideas what I am missing?
I think if I am right you are looking for something like this
SELECT DATEDIFF(day, [Promise Date], [Date Recieved])/100;
If right you can get more details here
since dates in access are effectively stored as DOUBLE, I would recommend converting to the SQL float type to handle any part days
(cast([Promise Date] as float) - cast([Date Recieved] as float))/100
check out the following example, the different ideas here give quite different answers
declare #x as datetime = '19960420 15:05:48';
declare #y as datetime = '19960423 18:09:23';
select (CAST(#y as float) - CAST(#x as float)) / 100
select (CAST(#y as int) - CAST(#x as int)) / 100
select datediff(day,#x,#y) / 100
select cast(datediff(day,#x,#y) as float) / 100
Access should treat the dates as floats, with the fractional part representing time, and the integer part representing days
Declare #pd Date = '2019-01-15'
Declare #dr Date = '2019-01-12'
Select Cast(DATEDIFF(d,#dr,#pd) As Float) /100
Result
0.03
UPDATE: As per Cato's comment to allow for DateTime
Declare #pd DateTime = '2001-01-01 19:00:00'
Declare #dr DateTime = '2001-01-05 13:00:00'
Select (Cast(DATEDIFF(hh,#dr,#pd) As Float)/24) / 100
Result:
-0.0375

Cast or convert DD-MON-YYYY AM/PM to YYYY-MM-DD

I'm stuck in finding an answer on how to convert:
07-DEC-18 01.00.54.984000 PM to 2018-12-07 13.00.54.984000
I think the time of 01.00.54 PM is 13hours , 0 minutes and 54 seconds
I have try to convert with 112 but still i can't find out how to cast or convert this.
Below is one method that converts the date and time portions separately, and then uses DATEADD to combine the results. This assumes the actual time precision is not greater than milliseconds. Note that you need to use datetime2 instead of datetime to avoid rounding to 1/300 milliseconds.
DECLARE #DateTimeString varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT DATEADD(
millisecond
, DATEDIFF(millisecond, '', CAST(REPLACE(SUBSTRING(#DateTimeString, 11, 8), '.', ':') + RIGHT(#DateTimeString, 10) AS time))
, CAST(LEFT(#DateTimeString, 9) AS datetime2)
);
This converts your value to the datatype it should be, a datetime2(6). Date and time datatypes don't have formats, if you're storing them in a particular format you're doing it wrong (as it means you're storing the value as a varchar).
DECLARE #YourDate varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT V.YD,
TRY_CONVERT(datetime2(6),F.FormatedYD,106)
FROM (VALUES(#YourDate)) V(YD)
CROSS APPLY (VALUES(STUFF(STUFF(V.YD,13,1,':'),16,1,':'))) F(FormatedYD);
If this was a table, then I would fix your actual column datatype by doing the following:
UPDATE YT
SET YourDateColumn = CONVERT(varchar(30),TRY_CONVERT(datetime2(6),F.FormatedYD,106),126)
FROM YourTable YT
CROSS APPLY (VALUES(STUFF(STUFF(YT.YourDateColumn,13,1,':'),16,1,':'))) F(FormatedYD);
ALTER TABLE YourTable ALTER COLUMN YourDateColumn datetime2(6);

Conversion into a time format

there's a query where I get this error:
Conversion failed when converting date and/or time from character string.
Here's the query:
Select cast(RESULT_APPROVE_FULL_DATE as date) as RESULT_APPROVE_FULL_DATE, dtvl18, cast(RESULT_APPROVE_FULL_DATE as time) as RESULT_APPROVE_FULL_DATE_2, tdvl18
from #a1
left join #b1
on ADNR18=PATIENT_ID
and INST18=isuf_lab
and STNR18=request_number
and cast(RESULT_APPROVE_FULL_DATE as date)= cast(cast(dtvl18 as varchar) as date)
and cast(RESULT_APPROVE_FULL_DATE as time)=cast(cast(tdvl18 as varchar) as time)
The problem definitely lies in the last clause, since when I remove it, everything works )but I need that one). Namely, the problem is in conversion of tdvl18 (decimal(4,0), null) into a time format.
As it can be inferred, the tdvl18 field looks like this, for example: 947, 1525, 2359 etc. How can these decimal values be converted into a time format (hh:mm:ss.nnnnnnn)?
Thanks!
It is failing because SQL Server is failing to recognise string values as valid times. So your current errors can be reproduced with:
declare #someval as varchar(10) = '525'
select cast(#someval as time)
-- Conversion failed when converting date and/or time from character string.
If you format the values with a : in the correct place (before the last 2 digits) using the STUFF method, then the conversion should work for your values:
declare #someval as varchar(10) = '525'
select cast(stuff(#someval, len(#someval) - 1,0, ':') as time)
-- 05:25:00.0000000
This seems to work directly on decimal values too so you can avoid casting to varchar first:
declare #someval as decimal(4,0) = 525
select cast(stuff(#someval, len(#someval) - 1,0, ':') as time)
-- 05:25:00.0000000
Changing your last clause to this might work, assuming RESULT_APPROVE_FULL_DATE is casting to a time value correctly:
and cast(RESULT_APPROVE_FULL_DATE as time)
= cast(stuff(tdvl18, len(tdvl18) - 1,0, ':') as time)

Resources