How to calculate the local datetime from a utc datetime in tsql (sql 2005)?

前端 未结 10 1343
Happy的楠姐
Happy的楠姐 2021-02-02 14:13

i want to loop over a period of time in tsql, and print the utc datetimes and our local variant. We live in UTC +1, so i could easily add 1 hour, but in the summertime we live i

10条回答
  •  一向
    一向 (楼主)
    2021-02-02 15:06

    I've been waiting for 5 years for a more elegant solution but since one has not emerged, I'll post what I've been using thus far...

    CREATE FUNCTION [dbo].[UDTToLocalTime](@UDT AS DATETIME)  
    RETURNS DATETIME
    AS
    BEGIN 
    --====================================================
    --Set the Timezone Offset (NOT During DST [Daylight Saving Time])
    --====================================================
    DECLARE @Offset AS SMALLINT
    SET @Offset = -5
    
    --====================================================
    --Figure out the Offset Datetime
    --====================================================
    DECLARE @LocalDate AS DATETIME
    SET @LocalDate = DATEADD(hh, @Offset, @UDT)
    
    --====================================================
    --Figure out the DST Offset for the UDT Datetime
    --====================================================
    DECLARE @DaylightSavingOffset AS SMALLINT
    DECLARE @Year as SMALLINT
    DECLARE @DSTStartDate AS DATETIME
    DECLARE @DSTEndDate AS DATETIME
    --Get Year
    SET @Year = YEAR(@LocalDate)
    
    --Get First Possible DST StartDay
    IF (@Year > 2006) SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-03-08 02:00:00'
    ELSE              SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-04-01 02:00:00'
    --Get DST StartDate 
    WHILE (DATENAME(dw, @DSTStartDate) <> 'sunday') SET @DSTStartDate = DATEADD(day, 1,@DSTStartDate)
    
    
    --Get First Possible DST EndDate
    IF (@Year > 2006) SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-11-01 02:00:00'
    ELSE              SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-10-25 02:00:00'
    --Get DST EndDate 
    WHILE (DATENAME(dw, @DSTEndDate) <> 'sunday') SET @DSTEndDate = DATEADD(day,1,@DSTEndDate)
    
    --Get DaylightSavingOffset
    SET @DaylightSavingOffset = CASE WHEN @LocalDate BETWEEN @DSTStartDate AND @DSTEndDate THEN 1 ELSE 0 END
    
    --====================================================
    --Finally add the DST Offset 
    --====================================================
    RETURN DATEADD(hh, @DaylightSavingOffset, @LocalDate)
    END
    
    
    
    GO
    

    Notes:

    This is for North American servers that observer Daylight Saving Time. Please change the variable @Offest to the Timezone offset of the server running the SQL function (While NOT Observing the Daylight Savings time)...

    --====================================================
    --Set the Timezone Offset (NOT During DST [Daylight Saving Time])
    --====================================================
    DECLARE @Offset AS SMALLINT
    SET @Offset = -5
    

    As the DST rules change update them here...

    --Get First Possible DST StartDay
    IF (@Year > 2006) SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-03-08 02:00:00'
    ELSE              SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-04-01 02:00:00'
    --Get DST StartDate 
    WHILE (DATENAME(dw, @DSTStartDate) <> 'sunday') SET @DSTStartDate = DATEADD(day, 1,@DSTStartDate)
    
    
    --Get First Possible DST EndDate
    IF (@Year > 2006) SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-11-01 02:00:00'
    ELSE              SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-10-25 02:00:00'
    --Get DST EndDate 
    WHILE (DATENAME(dw, @DSTEndDate) <> 'sunday') SET @DSTEndDate = DATEADD(day,1,@DSTEndDate)
    

    Cheers,

提交回复
热议问题