Получение сегодняшнего полуночного времени в формате UTC - PullRequest
3 голосов
/ 04 ноября 2011

У меня есть следующий запрос, который вычисляет сегодняшнее полночное значение (UTC) как дату и время:

SELECT CONVERT(DATE,GETDATE())+(GETDATE()-GETUTCDATE())

Результат: 2011-11-03 19:00:00.000 (для GMT-5 4 ноября 2011 г.)

Мало того, но иногда он возвращает такие значения:

2011-11-03 19:00:00.003
2011-11-03 19:00:00.007
2011-11-03 19:00:00.010

..., что не так!

Должен быть лучший способ сделать это.

Ответы [ 2 ]

3 голосов
/ 04 ноября 2011

Я уже ответил на это с помощью решения с использованием DATEADD и DATEDIFF с GETDATE () и GETUTCDATE (), аналогично примеру, приведенному в исходном вопросе, но с тех пор я обнаружил тип данных datetimeoffset добавлено в SQL Server 2008 .Это сохраняет дату и время вместе со смещением часового пояса.

Способ использования этого типа будет зависеть от того, хотите ли вы изменить тип данных существующих данных.Если вы не хотите ничего менять, следующий оператор вернет тип datetime с местным временем полуночи:

SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, 
    CONVERT(date, GETDATE())), 
    DATENAME(TzOffset, SYSDATETIMEOFFSET())))

Вы также можете преобразовать любое время UTC в местное время, используя:

SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, 
        @myutctime, 
        DATENAME(TzOffset, SYSDATETIMEOFFSET())))

Тип datetimeoffset доступен только с использованием SQL2008 и выше.Если вам нужно сделать это с 2005 г. и ниже, вы можете использовать решение, аналогичное решению в исходном вопросе, но измененное, чтобы учесть тот факт, что GETDATE() - GETUTCDATE() не является атомарной операцией и, вероятно, потребует разницы в миллисекундах междуоба выполняются.

SELECT DATEADD(minute, 
    DATEDIFF(minute, GETUTCDATE(), GETDATE()), 
    CONVERT(datetime, CONVERT(date, GETDATE())))

Это займет число минут между GETDATE() и GETUTCDATE() и добавит их к местному полуночному времени.К сожалению, вам придется конвертировать обратно из даты в дату и время, так как DATEADD не будет работать с минутами, если вы укажете дату.Я бы предложил обернуть это в пользовательскую функцию, чтобы она выглядела менее многословно, например

CREATE FUNCTION dbo.MidnightASUTC(@dt as datetime)
RETURNS datetime
AS
BEGIN
    RETURN DATEADD(minute, 
        DATEDIFF(minute, GETUTCDATE(), GETDATE()),
        CONVERT(datetime, CONVERT(date, @dt)))
END

SELECT dbo.MidnightAsUTC(GETDATE())
0 голосов
/ 04 ноября 2011

Для конкретного сценария, подобного тому, который вы описали («сегодняшнее полночное значение (UTC) как дата-время»), программный подход имеет смысл, но если вам когда-нибудь понадобится расширить его на другой вопрос (какой была полночьUTC этим летом?), Вы можете использовать таблицу календаря (для учета таких вещей, как летнее время и т. Д.).

...