Вот функция, которая работает с историческими данными. Я написал это для британского летнего времени, которое, к сожалению, происходит в последнее воскресенье марта и октября, что делает логику немного запутанной.
В основном, жестко закодированная часть 01/03 ищет последнее воскресенье марта, а 01/10 ищет последнее воскресенье октября (когда часы идут вперед и назад). ПРИМЕЧАНИЕ: ЕСЛИ ВАШ СЕРВЕР ИСПОЛЬЗУЕТ НАЦИОНАЛЬНЫЕ ДАТЫ США, ОБРАТИТЕСЬ К ЭТИМ ДВУМЯ ЧАСТЯМ ДАТЫ ДО 03/01 и 10/01 !!!!
Таким образом, вы указываете дату в формате UTC, и она автоматически определит, является ли историческая дата BST или GMT. Не самая лучшая вещь для использования с большим набором данных, но это решение.
Запустите этот сценарий, чтобы создать функцию и вызвать ее в своем выборе. В SQL 2008 есть проблема с пользовательскими функциями, кажется, он помещает красную линию под код, но он все еще запускает ее, пока вы используете префикс dbo (SELECT dbo.UTCConvert (yourdate) для его запуска)
CREATE FUNCTION [dbo].[UTCConvert]
(
@p1 datetime
)
RETURNS datetime
AS
BEGIN
DECLARE @Result datetime
RETURN CASE
WHEN
@p1 >
(DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,'01/03/' + CAST(DATEPART(year,@p1) as CHAR)),30))/7*7,'19000107'))
AND
@p1<
(DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,'01/10/' + CAST(DATEPART(year,@p1) as CHAR)),30))/7*7,'19000107'))
THEN (DATEADD(HH, 1, @p1))
ELSE @p1
END
END