sql-server - 获取今天的午夜时间作为 UTC

标签 sql-server sql-server-2008 sql-server-2008-r2

我有以下查询将今天的午夜值 (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/

相关文章:

SQL 按列表排序

sql - 解析 XML 以构建动态查询

sql - 如果列存在则使用列值

sql - 在SQL Server中,像 "use <<DatabaseName>>",如何对 "use <<ServerName>>"查询命令

java - 检索 ResultSet 值时获取 IN 参数而不是行

sql - 在 CASE 语句中使用 LIKE

sql - 设置语句在SQL查询的if子句中不起作用

sql-server - SSIS 错误 : "ODBC Source" failed validation and returned validation status "VS_NEEDSNEWMETADATA"

c# - SQL LIKE % NOT SEARCHING

sql-server - 如何在子查询中返回多个结果?