5

我在 SQL Server 2008 R2 数据库中有几列,我需要将它们从本地时间(sql server 所在的时区)转换为 UTC。

我在 StackOverflow 上看到了很多类似的问题,但答案都无法在夏令时正常工作,它们只考虑当前的差异并偏移日期。

4

2 回答 2

7

我根本找不到任何方法单独使用 T-SQL。我使用 SQL CLR 解决了它:

public static class DateTimeFunctions
{
    [SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static DateTime? ToLocalTime(DateTime? dateTime)
    {
        if (dateTime == null) return null;
        return dateTime.Value.ToLocalTime();
    }

    [SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static DateTime? ToUniversalTime(DateTime? dateTime)
    {
        if (dateTime == null) return null;
        return dateTime.Value.ToUniversalTime();
    }
}

以及以下注册脚本:

CREATE FUNCTION ToLocalTime(@dateTime DATETIME2) RETURNS DATETIME2 AS EXTERNAL NAME AssemblyName.[AssemblyName.DateTimeFunctions].ToLocalTime; 
GO
CREATE FUNCTION ToUniversalTime(@dateTime DATETIME2) RETURNS DATETIME2 AS EXTERNAL NAME AssemblyName.[AssemblyName.DateTimeFunctions].ToUniversalTime; 

被迫付出这样的努力来转换为UTC时间和从UTC时间转换是一种耻辱。

请注意,这些函数将本地时间解释为服务器本地时间。建议将客户端和服务器设置为相同的时区以避免任何混淆。

于 2012-06-16T12:18:33.687 回答
1
    DECLARE @convertedUTC datetime, @convertedLocal datetime
    SELECT DATEADD(
                    HOUR,                                    -- Add a number of hours equal to
                    DateDiff(HOUR, GETDATE(), GETUTCDATE()), -- the difference of UTC-MyTime
                    GetDate()                                -- to MyTime
                    )

    SELECT @convertedUTC = DATEADD(HOUR,DateDiff(HOUR, GETDATE(), GETUTCDATE()),GetDate()) --Assign the above to a var

    SELECT DATEADD(
                    HOUR,                                    -- Add a number of hours equal to
                    DateDiff(HOUR, GETUTCDATE(),GETDATE()), -- the difference of MyTime-UTC
                    @convertedUTC                           -- to MyTime
                    )

    SELECT @convertedLocal = DATEADD(HOUR,DateDiff(HOUR, GETUTCDATE(),GETDATE()),GetDate()) --Assign the above to a var


    /* Do our converted dates match the real dates? */
    DECLARE @realUTC datetime = (SELECT GETUTCDATE())
    DECLARE @realLocal datetime = (SELECT GetDate())

    SELECT 'REAL:', @realUTC AS 'UTC', @realLocal AS 'Local'
    UNION
    SELECT 'CONVERTED:', @convertedUTC AS 'UTC', @convertedLocal AS 'Local'
于 2012-08-05T05:30:12.677 回答