如何在SQL Server中创建夏令时开始和结束功能

Ama*_*ine 14 sql sql-function sql-server-2008 dst

我需要在SQL服务器中创建一个函数,该函数返回夏令时开始日期时间和夏令时结束日期时间.

我在网上看到了一些例子,但他们都使用了3月的第1个日期和11月的第1个日期,这在技术上并不正确.

夏令时从3月的第2个星期日凌晨2点开始,到11月的第一个星期日凌晨2点结束.

我从下面的代码开始,但我确定它错了.任何帮助表示赞赏!:)

DECLARE @DSTSTART DATETIME

SELECT @DSTSTART = CASE WHEN 
DATEPART(MONTH, SYSDATETIME()) = 3
AND DATEPART(weekday, SYSDATETIME()) = 1
AND DATEDIFF(week,dateadd(week, datediff(week, 0, dateadd(month, datediff(month, 0, SYSDATETIME()), 0)), 0), SYSDATETIME() - 1) = 2
AND DATEPART(HOUR, SYSDATETIME()) = 2
THEN SYSDATETIME()
END
RETURN (@DSTSTART)
END
GO
Run Code Online (Sandbox Code Playgroud)

Jam*_*e F 17

不要忘记,夏令时时间表会根据国家/地区而变化,并且多年来也会发生变化:例如,当前的美国系统于2007年生效.

假设你想要美国当前的系统,这是任何一年的答案的一种形式.

SET DATEFIRST 7

DECLARE @year INT = 2013
DECLARE
    @StartOfMarch DATETIME ,
    @StartOfNovember DATETIME ,
    @DstStart DATETIME ,
    @DstEnd DATETIME



SET @StartOfMarch = DATEADD(MONTH, 2, DATEADD(YEAR, @year - 1900, 0))
SET @StartOfNovember = DATEADD(MONTH, 10, DATEADD(YEAR, @year - 1900, 0));
SET @DstStart = DATEADD(HOUR, 2,
                        DATEADD(day,
                                ( ( 15 - DATEPART(dw, @StartOfMarch) ) % 7 )
                                + 7, @StartOfMarch))
SET @DstEnd = DATEADD(HOUR, 2,
                      DATEADD(day,
                              ( ( 8 - DATEPART(dw, @StartOfNovember) ) % 7 ),
                              @StartOfNovember))


SELECT
    @DstStart AS DstStartInUS ,
    @DstEnd AS DstEndInUS
Run Code Online (Sandbox Code Playgroud)

或作为函数,但您必须知道DateFirst设置为7,否则数学将关闭.

CREATE FUNCTION GetDstStart ( @Year AS INT )
RETURNS DATETIME
AS
    BEGIN

        DECLARE
            @StartOfMarch DATETIME ,
            @DstStart DATETIME 

        SET @StartOfMarch = DATEADD(MONTH, 2,
                                    DATEADD(YEAR, @year - 1900, 0))
        SET @DstStart = DATEADD(HOUR, 2,
                                DATEADD(day,
                                        ( ( 15 - DATEPART(dw,
                                                          @StartOfMarch) )
                                          % 7 ) + 7, @StartOfMarch))
        RETURN @DstStart
    END

GO;


CREATE FUNCTION GetDstEnd ( @Year AS INT )
RETURNS DATETIME
AS
    BEGIN
        DECLARE
            @StartOfNovember DATETIME ,
            @DstEnd DATETIME

        SET @StartOfNovember = DATEADD(MONTH, 10,
                                       DATEADD(YEAR, @year - 1900, 0))
        SET @DstEnd = DATEADD(HOUR, 2,
                              DATEADD(day,
                                      ( ( 8 - DATEPART(dw,
                                                       @StartOfNovember) )
                                        % 7 ), @StartOfNovember))
        RETURN @DstEnd
    END
Run Code Online (Sandbox Code Playgroud)


Bri*_*ork 5

就个人而言,我认为在11月找到第一个星期日比在3月找到第二个星期日要容易。幸运的是,如果找到一个,就可以找到另一个,因为它们之间总是有238天的时间。因此,这里有一个方便的函数来查找Dst的结尾:

create function GetDstEnd (
                           @Year int
                          )
returns datetime
as
begin

   declare @DstEnd datetime;

   ;with FirstWeekOfNovember
   as (
       select top(7)
              cast(@Year as char(4))
            + '-11-0'
            + cast(row_number() over(order by object_id) as char(1))
            + ' 02:00:00'
              'DST_Stops'
         from sys.columns
      )
   select @DstEnd = DST_Stops
     from FirstWeekOfNovember
    where datepart(weekday,DST_Stops) = 1

   return @DstEnd;

end;
Run Code Online (Sandbox Code Playgroud)

现在,“开始Dst”具有相同的功能,仅早238天。

create function GetDstStart (
                             @Year int
                            )
returns datetime
as
begin;

   declare @DstStart datetime;

   ;with FirstWeekOfNovember
   as (
       select top(7)
              cast(@Year as char(4))
            + '-11-0'
            + cast(row_number() over(order by object_id) as char(1))
            + ' 02:00:00'
              'DST_Stops'
         from sys.columns
      )
   select @DstStart = dateadd(day,-238,DST_Stops)
     from FirstWeekOfNovember
    where datepart(weekday,DST_Stops) = 1

   return @DstStart;

end;
go
Run Code Online (Sandbox Code Playgroud)

  • 我想你误会了,@ GoldBishop-在任何一年中,从3月的第二个星期日到11月的第一个星期日之间总是有238天。year年是在三月之前,因此它是否有28天或29天都没有关系。我发现在11月的第一个星期日再减去238天比在3月的第二个星期日再加上238天容易。 (3认同)