两个日期之间的SQL Server DateDiff返回不准确的值

时间:2017-10-16 01:18:11

标签: sql sql-server tsql sql-server-2014 rdbms

我正在尝试通过ETL作业将字符串转换为DateTimeOffset(在SQL Server中)。基本上,我的字符串看起来像'2017-10-15',我希望将其转换为DatetimeOffset(来自当前的数据库服务器)。

SELECT
    SWITCHOFFSET(DATEADD(mi, DATEDIFF(MI, GETDATE(), GETUTCDATE()), CAST(@DateInString  + ' 00:00:00' AS DATETIMEOFFSET)), DATENAME(tzoffset, SYSDATETIMEOFFSET()))

我在这个陈述中遇到了一些奇怪的问题,因为最终输出将落后+1 / -1分钟。至少每10个记录/百万发生这种情况。我试图确定问题,我可以看到问题是DATEDIFF()方法返回+/- 1分钟。

SELECT DATEDIFF(MI, GETDATE(), GETUTCDATE()) 

这应该完全返回-600(因为我的数据库服务器UTC是+10)。但是,对于少数记录,它返回-599或601。我在我的存储过程中将它们作为单个select语句执行,并将其作为参数返回。

对于SQL如何在同一select语句中检测GETDATE()GETUTCDATE()的两个不同日期时间值,这很奇怪。

有没有办法强制SQL在DATEDIFF个参数中获取完全相同的日期,或者我在这里遗漏了什么?提前致谢

我正在使用SQL Server 2014(v12.0)。

存储过程:

CREATE PROCEDURE dbo.SPConvertDateTimeOffset
    @DateInString VARCHAR(10),
    @DateTimeOffset_Value DATETIMEOFFSET OUTPUT,
    @Datediff_Value INT OUTPUT
AS 
BEGIN 
    -- This line returns +/- 1
    SELECT @Datediff_Value = DATEDIFF(MI, GETDATE(), GETUTCDATE())  

    SELECT @DateTimeOffset_Value = SWITCHOFFSET(DATEADD(mi, @Datediff_Value, CAST(@DateInString  + ' 00:00:00' AS DATETIMEOFFSET)), DATENAME(tzoffset, SYSDATETIMEOFFSET()))
END

2 个答案:

答案 0 :(得分:0)

这两个功能不会同时执行。因此,大约1万次(在你的测试中)时间是在一分钟边界的两侧。

如果您只想要时区,可以尝试:

  

选择datepart(tz,SYSDATETIMEOFFSET())

答案 1 :(得分:0)

@GordonLinoff解释了为什么会发生这种情况:由于函数在稍微不同的时间执行,它们可能会返回不同的时间。

要解决此问题,请尝试以下方法:

DECLARE @DateTimeOffset_Value Datetimeoffset
DECLARE @Datediff_Value INT, @DateInString VARCHAR( 10 )
SET @DateInString = CONVERT( VARCHAR, GETDATE(), 112 )
SET @DateTimeOffset_Value = TODATETIMEOFFSET( @DateInString, DATENAME(tzoffset,SYSDATETIMEOFFSET()))
SET @Datediff_Value = DATEDIFF( MI, @DateInString, @DateTimeOffset_Value )
SELECT @DateInString, @DateTimeOffset_Value, @Datediff_Value

它不使用当前日期比较。

注意:在日间保存更改期间,您可能会获得与预期值不同的值,具体取决于代码运行的时间。

有关如何处理DTS更改的更多解决方案,请查看https://dba.stackexchange.com/questions/28187/how-can-i-get-the-correct-offset-between-utc-and-local-times-for-a-date-that-is