Sql Server Local в UTC преобразование
Я ломал голову над этим в течение последнего дня или около того, и я надеюсь, что кто-то здесь может пролить немного света.
Я недавно мигрировал на Amazon RDS SQL Server, который находится в UTC. Тем не менее, все мои времена в базе данных находятся в местном часовом поясе (Западная Европа). Моя следующая задача - преобразовать все эти DateTimes в UTC.
Я думаю, что самым быстрым способом будет сделать это непосредственно на Sql Server, поскольку нет простого способа учета DST, я прибегнул к пользовательской функции в SQL CLR (как видно из другого ответа здесь), которая не ' т работает в данный момент. Это выглядит так:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime ToUniversal(SqlDateTime dt)
{
if (dt.IsNull)
{
return SqlDateTime.Null;
}
else
{
return dt.Value.ToUniversalTime();
}
}
Функция, однако, не конвертируется из местного в универсальное время. Пример,
select creationtime, dbo.ToUnversal(CreationTime) as New from testtable
Возвращает те же две даты и времени, которые также являются исходными.
Это почему? Это потому, что Sql Server уже находится в UTC, поэтому он распознает это и не преобразует его дальше?
Кроме того, если у вас есть другие рекомендуемые подходы, пожалуйста, добавьте их. Я уже пытался решить это с небольшим приложением.NET, но это очень медленно с моей базой данных 120 ГБ.
1 ответ
Немного опоздал на игру, ну да ладно..
Помните, что если вы идете по этому пути.NET, вы должны выполнить преобразование на исходном сервере, если для источника и назначения установлены разные (системные) часовые пояса! .NET использует часовой пояс, установленный в Windows на исполняющей машине.
IIRC, DateTimes из SQL будут переданы.NET с DateTimeKind.Unspecified. Если дело обстоит именно так, DateTime.ToUniversalTime всегда предполагает, что вы указали местное время, и должно конвертироваться очень хорошо.
Однако, если системный часовой пояс совпадает с часовым поясом исходного сервера (что-то отличное от UTC), и если DateTimes неправильно возвращаются с DateTimeKind.Universal, так что ToUniversal ничего не делает, вы можете принудительно преобразовать DateTimes, выполнив:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime ToUniversal(SqlDateTime dt)
{
if (dt.IsNull)
{
return SqlDateTime.Null;
}
else
{
// SpecifyKind changes the Kind property without changing the actual
var tempDate = DateTime.SpecifyKind(dt.Value, DateTimeKind.Local);
return tempDate.ToUniversalTime();
}
}