July 23, 2004 at 7:12 am
I have a SQL Server running in GMT. I have been passed a VARCHAR which holds a date and time in BST . I want to be able to convert the VARCHAR into a DateTime and also convert the date into GMT. I have no problems paseing the VARCHAR into a DateTime but I can't see a way of converting a time in BST into a time in GMT.
July 23, 2004 at 7:19 am
can you post an example of the data - sureley you just need to use dateadd(hh,1,[date]) and dateadd(hh,-1,[date]) to go backwards and forwards one hour ???
MVDBA
July 23, 2004 at 7:20 am
dateadd( h, x, cast( datefield as datetime))
where x is the hour difference. datefield is your column.
July 23, 2004 at 7:42 am
Frank Kalis pointed me toward a way to find out the local timezone using the registry :
DECLARE @delta INT
EXEC master.dbo.xp_regread
'HKEY_LOCAL_MACHINE'
, 'SYSTEM\CurrentControlSet\Control\TimeZoneInformation'
, 'ActiveTimeBias'
, @delta OUT
SELECT
GETDATE() AS Local_Time
, DATEADD( Minute, @delta,GETDATE()) AS Greenwich_Mean_Time
, @delta / 60 AS Delta
Also check out http://www.sqlservercentral.com/columnists/dasanka/datetimevaluesandtimezones.asp
by Dinesh Asanka.
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
July 23, 2004 at 7:43 am
The problem is BST is sometimes the same as GMT and sometimes it is fowards and hour. The logic for when the change happens is not trivial and I was wondering if there was a simple way around it rather than having to do it by hand. A defination of bst is:
British Summer Time (BST) is the daylight saving time in effect in the United Kingdom between the last Sunday in March and the last Sunday in October each year. BST is the same as Central European Time: one hour in advance of Greenwich Mean Time, UTC+1.
July 23, 2004 at 7:49 am
Maybe you can read the reg-key from within your application's front-tier (not at the mid-tier or server) and have the timezoneshift delivered by your application.
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
July 23, 2004 at 7:52 am
so what you're asking really is -- is there a way to detect whether it's BST or not from the current date? and then apply a date modifier if it is ??????
MVDBA
July 23, 2004 at 7:52 am
Would rather not have to do that as I would mean rewriting rather a lot of code.
July 23, 2004 at 7:56 am
I know that the date is in BST my question is: is there an easy way of converting a date in BST into GMT. It is not as simple as a date add since BST is sometimes an hour ahead of GMT sometimes it is the same time.
July 23, 2004 at 8:04 am
alzdba: Getting the registry key out like you suggest would work very well if the server was in BST but unfortinatly it is in GMT so I can get the ActiveTimeBias for BST. Still that is a neat trick I will rember that one.
July 23, 2004 at 8:05 am
Maybe this udf can be used as a workaround :
if exists (select * from dbo.sysobjects where id = object_id('dbo.udf_Get_Last_DayNr'))
begin
Drop Function dbo.udf_Get_Last_DayNr
print 'Dropped'
end
go
Create Function dbo.udf_Get_Last_DayNr
( @Start_DateTime AS datetime = '1900-01-01'
, @End_DateTime AS datetime
, @SearchDayNr as tinyint = 1
, @hh_time as char(2) = '00')
returns datetime
As
BEGIN
-- ALZDBA dd 24/07/2003
-- Determine last date from daynumber between two dates
-- Remark : Sunday = dayno 1 ... unless SET DATEFIRST { number | @number_var } is in use
if @Start_DateTime > @End_DateTime
begin
-- print '-- wrong INPUTPARAMETER(1)'
return(null)
end
if @SearchDayNr between 1 and 7
begin
set @SearchDayNr = @SearchDayNr
end
else
begin
-- print '-- wrong INPUTPARAMETER(3)'
return(null)
end
Declare @Dw_End_DateTime as smallint
Select @Dw_End_DateTime = DATEPART(dw,@End_DateTime)
Declare @Verschil as smallint
Select @Verschil = @Dw_End_DateTime - @SearchDayNr
if @Verschil = 0
begin
return convert(datetime,convert(varchar(11),@End_DateTime,121) + @hh_time + ':00:00')
end
else
begin
Select @Verschil = case when @Verschil < 1 then (7 + @Verschil ) * (-1)
else @Verschil * (-1)
end
Declare @Result_DateTime DateTime
Select @Result_DateTime = dateadd(dd, @Verschil ,@End_DateTime)
if @Result_DateTime < @Start_DateTime
begin
-- print 'Result before startdate'
return (NULL)
end
else
begin
if @Result_DateTime > @End_DateTime
begin
-- print 'Result after enddate'
return (null)
end
else
begin
return convert(datetime, convert(varchar(11),@Result_DateTime,121) + @hh_time + ':00:00')
end
end
end
Return(NULL)
END
go
GRANT EXECUTE ON dbo.udf_Get_Last_DayNr TO public
GO
-- execute it
select dbo.udf_Get_Last_DayNr ( '2004-03-01' , '2004-03-31', 1 , '02') as SummertimeOnDate
, dbo.udf_Get_Last_DayNr ( '2004-10-01' , '2004-10-31', 1 , '02') as SummertimeOffDate
You'll get the grip .
Or you can just check if there is a timedifference between your input and your sqlserver, if there is , it is summertime
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
July 23, 2004 at 8:22 am
alzdba: Hmm yes doing the conversion by hand does seem to be the only way. Thanks for the code.
Lionel
July 26, 2004 at 6:49 am
How about using a UDF? Here's an example:
CREATE FUNCTION dbo.fnGMT
(
@bstDateStr varchar(22)
)
RETURNS datetime
AS
BEGIN
-- British Summer Time (BST) is the daylight saving time in effect in the United Kingdom
-- between the last Sunday in March and the last Sunday in October each year.
-- BST is the same as Central European Time: one hour in advance of Greenwich Mean Time, UTC+1.
--
-- Normal = GMT (or WET, Western European Time)
-- Daylight Saving = BST = GMT + 1
-- All changes occur at 1am GMT
DECLARE @bstYearStr varchar(4), @bstDate datetime
DECLARE @bstStart datetime, @bstEnd datetime
SET @bstDate = Convert(datetime, @bstDateStr)
-- Compute Beginning and Ending DateTimes of BST
SET @bstYearStr = Convert(varchar(4), DatePart(yyyy, @bstDate))
SET @bstStart = Convert(datetime, '03/01/' + @bstYearStr + ' 01:00:00')
SET @bstEnd = Convert(datetime, '10/31/' + @bstYearStr + ' 01:00:00')
WHILE DatePart(dw, @bstStart) <> 1
SELECT @bstStart = DateAdd(d, 1, @bstStart)
WHILE DatePart(dw, @bstEnd) <> 1
SELECT @bstStart = DateAdd(d, -1, @bstStart)
IF @bstDate BETWEEN @bstStart AND @bstEnd
SET @bstDate = DateAdd(hh, -1, @bstDate)
RETURN @bstDate
END
/*
-- TEST
PRINT dbo.fnGMT('1/1/2004 00:00:00')
PRINT dbo.fnGMT('2/26/2004 00:00:00')
PRINT dbo.fnGMT('3/1/2004 00:00:00')
PRINT dbo.fnGMT('3/7/2004 00:00:00')
PRINT dbo.fnGMT('3/7/2004 01:00:00')
PRINT dbo.fnGMT('3/7/2004 02:00:00')
PRINT dbo.fnGMT('7/26/2004 00:00:00')
PRINT dbo.fnGMT('10/30/2004 00:00:00')
PRINT dbo.fnGMT('10/31/2004 00:00:00')
PRINT dbo.fnGMT('10/31/2004 01:00:00')
PRINT dbo.fnGMT('10/31/2004 00:59:59')
PRINT dbo.fnGMT('10/31/2004 02:00:00')
PRINT dbo.fnGMT('11/15/2004 00:00:00')
PRINT dbo.fnGMT('12/31/2004 00:00:00')
*/
July 26, 2004 at 7:27 am
We solved the same issue using an extended stored procedure. The complicated logic of reading the registry and adjusting for the bias and the complicated daylight savings time logic is all handled by the windows call SystemTimeToTzSpecificLocalTime. We just wrapped some code around it and it handles it. If you are not worried about handling daylight savings time issues then getdate() - getutcdate() will give you the bias from UTC time.
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply