代码之家  ›  专栏  ›  技术社区  ›  Andomar

Sql Server中的夏令时

  •  2
  • Andomar  · 技术社区  · 17 年前

    我们使用的是以C/Unix格式存储日期的旧应用程序。C时间基本上是自1970年1月1日以来的秒数。日期以整数形式存储在SQL Server数据库中。我正在为使用这些日期的报告编写视图。

    到目前为止,我正在使用以下功能将UNIX时间转换为本机日期时间:

    DateAdd(s,3600+unix_time,'1/1/1970')
    

    3600将从UTC转换为本地GMT+1时区。这在冬天是准确的,但在夏天,由于夏令时的原因,它需要休息一小时。

    3 回复  |  直到 17 年前
        1
  •  7
  •   Hans    14 年前

    实际上,上面的答案忽略了夏令时。如果当前不是夏令时,则夏令时期间内的日期将休息一小时,反之亦然。此外,许多不同国家的立法者喜欢让夏令时变得比需要的更复杂。

    基本上,如果可能的话,在SQL Server中尽量避免这种情况。客户端数据处理库通常可以正确地处理数据。如果您需要在数据库中使用时间戳,请考虑将它们转换为DATESTIME列,或者在使用客户端代码之前将日期值转换为时间戳,然后将它们用作查询参数。

        2
  •  1
  •   Tristan    12 年前

    我在UTC/GMT1中也遇到过类似的问题,虽然您希望在数据库中避免这种情况的许多陈述都是非常真实和有价值的建议,但并不总是能够完全避免这种情况。

    然而,当您使用GMT1时,您是幸运的,因为它的夏令时实际上是基于一种算法。(据我所知,与美国的夏令时不同,夏令时是由立法机构决定的。)

    由此,我能够制作这个将UTC日期时间输入转换为GMT1日期时间的存储过程。希望这有帮助;)

    CREATE PROCEDURE spUTCGMT1 @date AS DATETIME
    AS 
    BEGIN
         DECLARE @year AS INT = DATEPART( YYYY,@date)
         DECLARE @f AS INT = (FlOOR( (5 * @year) / 4) - FLOOR( @year / 100)+ FLOOR( @year / 400)) % 7
    
         IF(@date BETWEEN 
            DATEADD( DD,- ((@f + 5) % 7),(CAST(@year AS CHAR(4)) + '-03-31')) AND 
            DATEADD( DD,- ((@f + 2) % 7),(CAST(@year AS CHAR(4)) + '-10-31')))
         SELECT 
                DATEADD( HH,2,@date)
         ELSE
         SELECT 
                DATEADD( HH,1,@date)
    END
    
        3
  •  0
  •   Eric    17 年前

    您需要执行DateDiff(s,getutcdate(),getdate())+unix_时间,而不是3600,这将为您提供与UTC时间的正确偏移量。

    干杯
    埃里克