2015-06-18 3 views
2

Я хочу написать запрос, чтобы возвращать результаты только в 2 часа дня в Великобритании. Я также знаю, что EST на Лондонское время в настоящее время составляет 5 часов. Как я могу это сделать?Sql Server Уточнить время в другом часовом поясе

select * 
from table 
where blah blah 
and 2pm UK time < GETDATE() 
+1

Вам необходимо конвертировать 2pm UK (или BST или GMT в зависимости) в UTC, а затем сравнивать текущее время в UTC с эквивалентом 2pm GMT/BST в формате UTC. Этот ответ должен помочь http://stackoverflow.com/a/8038792/1370442 - дело со временем - это кошмар! – bUKaneer

ответ

2

Поскольку часовой пояс Великобритании может повлиять на летнее время, я предлагаю строить таблицу перехода на летнее время и с помощью, чтобы создать дату.

сослались Эта статья для этого решения: http://www.mssqltips.com/sqlservertip/3173/handle-conversion-between-time-zones-in-sql-server--part-1/

Создать таблицу:

CREATE TABLE dbo.TZCalendar 
(
    [Year]  Int PRIMARY KEY, 
    UTC_DST_Start SMALLDATETIME NOT NULL, 
    UTC_DST_End SMALLDATETIME NOT NULL, 
    ET_DST_Start AS CONVERT(SMALLDATETIME,DATEADD(HOUR, -4, UTC_DST_Start)), 
    ET_DST_End AS CONVERT(SMALLDATETIME,DATEADD(HOUR, -5, UTC_DST_End)) 
); 

SET DATEFIRST 7; 
;WITH cte(d,p) AS 
(
    -- all the years from 2000 through 50 years after the current year: 
    SELECT TOP (YEAR(GETDATE())-2000+51) DATEADD(YEAR,number,'20000101'), 
    CASE WHEN number < 7 THEN 1 ELSE 0 END -- year < 2007 = 1, else 0 
    FROM [master].dbo.spt_values WHERE [type] = N'P' ORDER BY number 
) 
INSERT dbo.TZCalendar([Year],UTC_DST_Start,UTC_DST_End) 
SELECT Year(d), 
-- First Sunday in April (< 2007) or second Sunday in March (>= 2007): 
DATEADD(HOUR, 7, DATEADD(DAY,(7-DATEPART(WEEKDAY,DATEADD(MONTH,2+p,d))+1)%7 
    +(7*ABS(p-1)),DATEADD(MONTH,2+p,d))), 
-- Last Sunday in October (< 2007) or first Sunday in November (>= 2007): 
DATEADD(HOUR, 6, DATEADD(DAY,(7-DATEPART(WEEKDAY,DATEADD(MONTH,10,d))+1)%7 
    -(7*p),DATEADD(MONTH,10,d))) 
FROM cte 
ORDER BY d; 

Далее, я хотел бы создать функцию, чтобы тянуть текущее время в Великобритании:

Create Function dbo.fnGetUKTime() 
Returns DateTime 
As Begin 
    Declare @London DateTime = GetUTCDate() 

    Declare @Offset Int = 0 

    Select @Offset = Case When @London Between UTC_DST_Start And UTC_DST_End Then 1 Else 0 End 
    From dbo.TZCalendar 
    Where Year = Year(@London) 

    Set @London = DateAdd(Hour, @Offset, @London) 

    Return @London 
End 
Go 

Тогда, вы можете ссылаться на это в своем запросе:

select * 
from table 
where blah blah 
and DatePart(Hour, dbo.fnGetUKTime()) > 14 
+0

Великобритания может быть GMT или BST (летнее время), так что это может быть на 1 час – bUKaneer

+1

@ bUKaneer А, я не думал об этом. Это немного усложняет это дело. – Siyual

+0

Например, я сейчас в Великобритании, и это 16:55, а не 15:55! –

2

Вы можете использовать datepart для определения текущего DateTime смещение (в минутах) сервера:

select datepart(tz, sysdatetimeoffset()) 

К примеру, в Великобритании на данный момент (во время BST), это дает 60.

Чтобы узнать, есть ли у вас до или после 2 часов дня в другой часовой пояс, вам нужно сравнить ваше текущее время с 2:00, плюс ваше смещение, за вычетом смещения в другом часовом поясе, так, например, 2 часа по английскому времени в ваше текущее время зона:

select dateadd(minute, -<current uk offset>, dateadd(minute, datepart(tz, sysdatetimeoffset()), cast('14:00' as time))) 

Обратите внимание, что текущее смещение часового пояса в Великобритании составляет 60 лет летом и 0 зимой. Если вас интересует только GMT, а не BST, вы можете опустить эту часть расчета.

+0

Просто добавьте - BST начинается в последнее воскресенье марта (IIRC, в 1 час. 00 мин.) И заканчивается в последнее воскресенье октября, когда вычисляется, совпадает ли текущая дата с BST, как упражнение для читателя ... –

Смежные вопросы