我有以下查询将今天的午夜值 (UTC) 计算为日期时间:
SELECT CONVERT(DATE,GETDATE())+(GETDATE()-GETUTCDATE())
结果:2011-11-03 19:00:00.000
(适用于 2011 年 11 月 4 日的 GMT-5)
不仅如此,有时它还会返回如下值:
2011-11-03 19:00:00.003
2011-11-03 19:00:00.007
2011-11-03 19:00:00.010
...,哪些是错误的!
必须有更好的方法来做到这一点。
最佳答案
我已经通过使用 DATEADD 和 DATEDIFF 以及 GETDATE() 和 GETUTCDATE() 的解决方案回答了这个问题,类似于原始问题中给出的示例,但从那以后我发现了 datetimeoffset数据类型 added in SQL Server 2008 .这会存储日期时间和时区偏移量。
如何使用此类型取决于您是否要更改现有数据的数据类型。如果您不想更改任何内容,则以下语句将返回本地时间为午夜的 datetime 类型:
SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset,
CONVERT(date, GETDATE())),
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
您还可以使用以下方法将任何 UTC 时间转换为本地时间:
SELECT CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset,
@myutctime,
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
datetimeoffset 类型只能使用 SQL2008 及以上版本。如果您需要在 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())
关于sql-server - 获取今天的午夜时间作为 UTC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8009968/