SQL 两个日期之间的服务器 DateDiff returns 值不准确
SQL Server DateDiff between two dates returns inaccurate values
我正在尝试通过 ETL 作业将字符串转换为 DateTimeOffset
(在 SQL 服务器中)。基本上,我的字符串看起来像“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 records/million 次发生一次。我试图确定问题,我可以看到问题出在 DATEDIFF()
方法 returning +/-1 分钟。
SELECT DATEDIFF(MI, GETDATE(), GETUTCDATE())
这应该正好是 return -600(因为我的数据库服务器 UTC 是 +10)。然而,它 returns 是 -599 或 601 的少数记录。我在我的存储过程中将它们作为单个 select 语句执行,并将其作为参数 return 执行。
这很奇怪 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
两个函数没有同时执行。因此,大约每 100,000 次中有 1 次(在您的测试中)时间位于分钟边界的两侧。
如果你只想要时区,你可以尝试:
select datepart(tz, SYSDATETIMEOFFSET())
@GordonLinoff 解释了为什么会发生这种情况:由于函数的执行时间略有不同,因此它们可能 return 不同的分钟。
要变通,试试这个:
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
它不使用当前日期比较。
注意:在夏令时更改期间,您可能会得到与预期不同的值,具体取决于代码 运行 的确切时间。
查看 https://dba.stackexchange.com/questions/28187/how-can-i-get-the-correct-offset-between-utc-and-local-times-for-a-date-that-is 以获取有关如何处理 DTS 更改的更多解决方案。
我正在尝试通过 ETL 作业将字符串转换为 DateTimeOffset
(在 SQL 服务器中)。基本上,我的字符串看起来像“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 records/million 次发生一次。我试图确定问题,我可以看到问题出在 DATEDIFF()
方法 returning +/-1 分钟。
SELECT DATEDIFF(MI, GETDATE(), GETUTCDATE())
这应该正好是 return -600(因为我的数据库服务器 UTC 是 +10)。然而,它 returns 是 -599 或 601 的少数记录。我在我的存储过程中将它们作为单个 select 语句执行,并将其作为参数 return 执行。
这很奇怪 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
两个函数没有同时执行。因此,大约每 100,000 次中有 1 次(在您的测试中)时间位于分钟边界的两侧。
如果你只想要时区,你可以尝试:
select datepart(tz, SYSDATETIMEOFFSET())
@GordonLinoff 解释了为什么会发生这种情况:由于函数的执行时间略有不同,因此它们可能 return 不同的分钟。
要变通,试试这个:
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
它不使用当前日期比较。
注意:在夏令时更改期间,您可能会得到与预期不同的值,具体取决于代码 运行 的确切时间。
查看 https://dba.stackexchange.com/questions/28187/how-can-i-get-the-correct-offset-between-utc-and-local-times-for-a-date-that-is 以获取有关如何处理 DTS 更改的更多解决方案。