我已经使用DATEADD和DATEDIFF溶液与GETDATE()和GETUTCDATE(),类似于原来的问题给出的例子回答了这个,但自那以后,我发现了datetimeoffset数据类型added in SQL Server 2008。这存储了日期时间以及时区偏移量。
您如何使用此类型取决于您是否要更改现有数据的数据类型。使用
SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset,
CONVERT(date, GETDATE())),
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
你也可以将任何UTC时间为本地时间:如果你不想改变什么,下面的语句将返回一个DateTime类型与午夜当地时间
SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset,
@myutctime,
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
只有使用SQL2008及更高版本才能使用datetimeoffset类型。如果您需要在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())
您需要在调用DATEDIFF时调用GETDATE()和GETUTCDATE():'DATEDIFF(hour,GETUTCDATE(),GETDATE())'来获得正确的结果,但我尝试了大约100次运行,最少得到正确的时间。 –
糟糕,我扭转了它。我也更改了使用DATEADD(分钟...)的答案,因为小时数方法不会处理与UTC时差1/2小时的国家/地区。 – Richard
我想知道是否存在性能损失与你提出的UDF,它是有意义的,使它成为一个内联TVF,返回1行/ 1列结果的值? –