Sql Server本地到UTC转换

时间:2014-05-26 17:12:44

标签: sql-server datetime utc sqlclr datetime-conversion

在最后一天左右,我一直在用这个破坏我的头,我希望这里有人可以解决这个问题。

我最近迁移到了UTC的Amazon RDS SQL Server。但是,我在数据库中的所有时间都在当地时区(西欧)。我的下一个挑战是将所有这些DateTime转换为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应用程序来解决这个问题,但是我的数据库容量为120GB时速度很慢。

1 个答案:

答案 0 :(得分:1)

比赛迟到了,但是很好......

请记住,如果你采用这种.NET方式,如果源和目标设置为不同的(系统)时区,则必须在源服务器上进行转换! .NET使用在执行机器上的Windows上设置的时区。

IIRC,SQL的DateTimes将通过DateTimeKind.Unspecified提供给.NET。如果是这种情况,DateTime.ToUniversalTime总是假设你给它一个本地时间,应该转换得很好。

但是,如果系统时区与源服务器时区匹配 - 不是UTC-并且DateTimes错误地返回DateTimeKind.Universal,那么ToUniversal什么也不做,您可以通过执行以下操作来强制转换DateTime: / p>

  [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();
    }
  }