fn_LocalTimeToUTC 的基本替代方案

osh*_*nen 2 sql-server t-sql functions sql-server-2017

我的云提供商阻止我访问fn_LocalTimeToUTCfn_UTCToLocalTime.

我将如何在不使用这些函数的情况下在 SQL 中手动和直接获得这两个函数提供的相同功能?

为了进一步简化,我们所有的用户都在英国。

Han*_*non 5

本地时间和 UTC 时间之间的差异可以通过查看GETDATE()和之间的差异来可靠地计算出来GETUTCDATE(),假设服务器操作系统配置为所需的“本地”时间(即,如果您的本地时间是欧洲中部时间,那么服务器必须配置为中欧时间)。

例如,请考虑以下情况:

GO
DROP FUNCTION dbo.LocalTimeToUTC;
GO
CREATE FUNCTION dbo.LocalTimeToUTC
(
    @LocalTime datetime
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
    SELECT UTCTime = DATEADD(MINUTE, DATEDIFF(MINUTE, GETDATE(), GETUTCDATE()), @LocalTime)
)
GO

DROP FUNCTION dbo.UTCToLocalTime;
GO
CREATE FUNCTION dbo.UTCToLocalTime
(
    @UTCTime datetime
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
    SELECT LocalTime = DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), GETDATE()), @UTCTime)
)
GO


SELECT *
FROM (
    VALUES ('2020-09-10T08:47:00')
    )
    v(LocalDate)
CROSS APPLY dbo.LocalTimeToUTC(v.LocalDate) u
CROSS APPLY dbo.UTCToLocalTime(u.UTCTime) l
Run Code Online (Sandbox Code Playgroud)

输出看起来像:

?????????????????????????????????????????????????????? ???????????????????????????
? 本地日期?UTC时间?当地时间 ?
?????????????????????????????????????????????????????? ???????????????????????????
? 2020-09-10T08:47:00 ?2020-09-10 13:47:00.000 ?2020-09-10 08:47:00.000 ?
?????????????????????????????????????????????????????? ???????????????????????????

为清楚起见,这只适用于假设您的所有客户端都在同一时区,并且安装的服务器与您所需的“本地”时区相匹配。

GETUTCDATE() 至少从 2008 年开始,所有版本的 SQL Server 都支持。

还值得注意的是,如果您在表中保存的日期时间值上使用它,并且您的本地时区使用夏令时,其中本地时间和 UTC 时间之间的差异在一年中有所不同,则您需要针对标准时间之间的差异进行调整和夏令时。

当您担心在时区之间进行转换时,在 SQL Server 中存储日期时间数据的一种更可靠的方法是使用datetimeoffset数据类型而不是datetime,并AT TIME ZONE在查询存储的值时使用修饰符。

这是如何工作的一个例子:

DECLARE @dt datetimeoffset;
SET @dt = GETDATE() AT TIME ZONE 'Central Standard Time';

SELECT @dt;
Run Code Online (Sandbox Code Playgroud)
(无列名)
2020-10-19 10:26:37.8100000-05:00

要获取 UTC 时间:

SELECT @dt AT TIME ZONE 'UTC';
Run Code Online (Sandbox Code Playgroud)
2020-10-19 15:26:37.8100000 +00:00