T-SQL:检查给定日期是否在夏令时中

时间:2015-10-30 20:22:12

标签: sql tsql

只使用纯t-sql,我需要检查太平洋时区的特定日期是否在夏令时下。我怎么做?

2 个答案:

答案 0 :(得分:2)

开始值和结束值是已知的,因此您可以构建一个DST表,其中包含每年的开始和结束时间,并进行检查。

此解决方案引用了这篇文章:http://www.mssqltips.com/sqlservertip/3173/handle-conversion-between-time-zones-in-sql-server--part-1/

Create Table TZCalendar
(
    Year            Int             Primary Key,
    UTC_DST_Start   SmallDateTime   Not Null,
    UTC_DST_End     SmallDateTime   Not Null,
    PT_DST_Start    As  Convert(SmallDateTime, DateAdd(Hour, -7, UTC_DST_Start)),
    PT_DST_End      As  Convert(SmallDateTime, DateAdd(Hour, -8, UTC_DST_End))
);
Go

Set DateFirst 7;
Go

;With Tally (Number) As
(
    Select  Row_Number() Over (Order By (Select Null)) - 1      Number
    From    (Values (0),(0),(0),(0),(0),(0),(0),(0),(0),(0))    a(n)
    Cross Join (Values (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
    Cross Join (Values (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
),Cte(d,p) As 
(
    Select  Top (Year(GetDate()) - 2000 + 51)
            DateAdd(Year, Number, '20000101'),
            Case When Number < 7 Then 1 Else 0 End
    From    Tally 
    Order By Number
)
Insert  TZCalendar
        (Year, UTC_DST_Start, UTC_DST_End)
Select  Year(d),
        DateAdd(Hour, 7, DateAdd(Day, (7 - DatePart(WeekDay, DateAdd(Month, 2 + p, d)) + 1) % 7
            + (7 * Abs(p - 1)), DateAdd(Month, 2 + p, d))),
        DateAdd(Hour, 6, DateAdd(Day, (7 - DatePart(WeekDay, DateAdd(Month, 10, d)) + 1) % 7
            - (7 * p), DateAdd(Month, 10, d)))
From    Cte
Order By d;

然后检查给定日期:

Select Case When Exists
(
    Select  *
    From    TZCalendar
    Where   @DateToCheck Between PT_DST_Start And PT_DST_End
)
Then 'Daylight Savings Time'
Else 'Standard Time'
End As IsDST

请记住,并非世界上所有地区都使用夏令时。

SQLFiddle Demo

答案 1 :(得分:0)

这是2015年以来的一个问题,但是,如果您可以使用SQL Server 2016,我将使用为此类情况和区域转换创建的快速功能:

Create Function GetOffsetValue( @dateToCheck DateTime2, @timeZoneId VarChar( 60 ) ) Returns Int
As Begin
    Return DatePart( TzOffset, @dateToCheck At Time Zone @timeZoneId ) --In minutes. Divide by 60 if more convenient
End

示例:

Select dbo.GetOffsetValue( Convert( DateTime2, '2019-01-01 13:00:00' ), 'Pacific Standard Time' ) --  -480
Select dbo.GetOffsetValue( Convert( DateTime2, '2019-10-01 13:00:00' ), 'Pacific Standard Time' ) --  -420

然后您可以检查该值是-480分钟(关闭DST)还是-420分钟(打开DST),也可以将其用于其他目的。