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.
Related
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);
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
In my table, I have a column that contains date in millisecond like this:
table a
dateinmili
1440301846096 //first six month date
1443589721039 //second six month date
I use that for my Android device and it works fine. When I want to use this time in a PROCEDURE in SQL Server and convert this time to human time (understandable for human) and date I have a problem.
I'm in Iran which uses UTC time in first six Persian date month 4.30 and 3.30 in second six month.
For convert date in PROCEDURE I use this code:
CONVERT(nVARCHAR(10),DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), DATEADD(ss,dateinmili/1000,'1970-01-01')),8) as date
DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), DATEADD(ss,dateinmili/1000,'1970-01-01')) as time
and here is my problem:
When I convert date in second six month and date registered in first six month of year, I get 1 hour difference between real time and converted time. I know that is because
DATEDIFF(mi, GETUTCDATE(), GETDATE())
method which return different between UTC time and local time when ever its called (in my example return 3:30 not 4:30 ) but I don't know how can I fix that?
I can add column which contain current UTC time but I am looking for another way.
update
I see this question and it's not my problem convert long to date.
My problem is in my country UTC time is not constant in whole year and change between 3.30 and 4.30, for example I have date registered in first six month (Persian six month) like 1440271800000 and convert it now which we are in second six month (Persian six month) and use this code for convert.
declare #unixTS bigint
set #unixTS = 1440271800000
select dateadd(ms, #unixTS%(3600*24*1000),
dateadd(day, #unixTS/(3600*24*1000), '1970-01-01 03:30:00.0')
)
I get this
2015-08-22 23:00:00.000
but it's not right date; the right date is:
2015-08-23 00:00:00.000
because when time registered UTC was 4.30 and not 3.30 but know when I convert
it UTC is 3.30.
I wish if there was a method in SQL which return past UTC time different; I mean put a date to that and return that time different between local time and gmt time my problem solved.
I hope you understand my problem.
In the US we have Daylight Savings Time in the summer, in most areas that means that we are also not fixed offset from UTC. Older versions of MS Dynamics CRM used to save everything in UTC, so when we wanted to export data in local time, we had a similar exercise. I created a set of SQL functions that would take the standard GMT offset and the datetime to I wanted to convert and figure out whether to apply the standard or DST offset and return the local datetime. If your offset follows a set of rules, then you can modify this:
CREATE function [dbo].[DC_GMTtoLocal]
(#OrigGMT datetime,
#StandardOffset int)
RETURNS datetime
AS
BEGIN
DECLARE #RevDate datetime
set #RevDate = CASE dbo.DC_DaylightSavingTime_IsInEffect(#OrigGMT)
WHEN 1 THEN DATEADD(hour, - #StandardOffset + 1, #OrigGMT) -- in DST
ELSE DATEADD(hour, - #StandardOffset, #OrigGMT) -- Not In DST
END
return #RevDate
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[DC_DaylightSavingTime_IsInEffect]
(#DtTime datetime)
RETURNS tinyint
AS
BEGIN
DECLARE #DLSStart datetime
, #DLSEnd datetime
, #DLSActive tinyint
SET #DLSActive = 0
If DATEADD(YEAR,3,GETDATE()) > #DtTime
BEGIN
SET #DLSStart =(SELECT dbo.DC_GetDaylightSavingsTimeStart(CONVERT(varchar,DATEPART(YEAR,#DtTime))))
SET #DLSEnd =(SELECT dbo.DC_GetDaylightSavingsTimeEnd(CONVERT(varchar,DATEPART(YEAR,#DtTime))))
IF #DtTime BETWEEN #DLSStart AND #DLSEnd
BEGIN
SET #DLSActive = 1
END
--SET #DLSActive = 0
END
RETURN #DLSActive
END
GO
CREATE function [dbo].[DC_GetDaylightSavingsTimeStart]
(#Year varchar(4))
RETURNS smalldatetime
as
--Start date: We evaluate the day of the week corresponding to the first day of the month and find the second Sunday of March using a Case statement
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
GO
CREATE function [dbo].[DC_GetDaylightSavingsTimeEnd]
(#Year varchar(4))
RETURNS smalldatetime
as
-- End date: We evaluate the day of the week corresponding to the first day of the month and find the first Sunday of March using a Case statement
begin
declare #DTSEndWeek smalldatetime
set #DTSEndWeek = '11/01/' + convert(varchar,#Year)
return case datepart(dw,dateadd(week,1,#DTSEndWeek))
when 1 then
dateadd(hour,2,#DTSEndWeek)
when 2 then
dateadd(hour,146,#DTSEndWeek)
when 3 then
dateadd(hour,122,#DTSEndWeek)
when 4 then
dateadd(hour,98,#DTSEndWeek)
when 5 then
dateadd(hour,74,#DTSEndWeek)
when 6 then
dateadd(hour,50,#DTSEndWeek)
when 7 then
dateadd(hour,26,#DTSEndWeek)
end
end
GO
I am working with stored procedure while coding I feel some difficulties to add an hour to a time.I mean I have already a predefined time like 08:00 in my database and now I want to add 4 to this time and I want to get result as 12:00. How can I achieve it?? The way which I tried is below,
ALTER PROCEDURE [dbo].[AttandenceEdit1](
#machid numeric(18,0),
)
AS
declare #time as time(0),#castedtime as time(0),
set #timein1=(select convert(time(0), from ShiftType where machId=#machid )// Value=08:00
print #time
set #addvalue =(DATEADD(HH,#timein1,4))
print #addvalue
I want the result 08:00+4=12:00
now it show error like Argument data type time is invalid for argument 2 of dateadd function
You have the arguments to dateadd in the wrong order. This:
declare #time as time(0)
set #time='08:00'
print #time
declare #addvalue time(0)
set #addvalue =(DATEADD(HOUR, 4, #time))
print #addvalue
Will result in:
08:00:00
12:00:00
There are other issues with your stored proc code though that you need to fix (like undeclared variables, surplus comma, logic).
There seems to be a bunch of issues in the code you've supplied, for example #timein1 and #addvalue are not declared.
So here's a simple example:
DECLARE #time AS TIME = '08:00:00'
SELECT #time AS OriginalTime,
DATEADD(HOUR, 4, #time) TimePlus4Hours
Produces:
OriginalTime | TimePlus4Hours
====================================
08:00:00.0000000 | 12:00:00.0000000
Reference:
DATEADD (Transact-SQL)
Returns a specified date with the specified number interval (signed integer) added to a specified datepart of that date.
DATEADD (datepart , number , date )
Try by Changing the DATEADD() function syntax like this:
set #addvalue =(DATEADD(HH,4,#timein1))
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)