在最后一天左右,我一直在用这个破坏我的头,我希望这里有人可以解决这个问题。
我最近迁移到了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时速度很慢。
答案 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();
}
}