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();
    }
  }
Другие вопросы по тегам