只使用纯t-sql,我需要检查太平洋时区的特定日期是否在夏令时下。我怎么做?
答案 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
请记住,并非世界上所有地区都使用夏令时。
答案 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),也可以将其用于其他目的。