【问题标题】:Sql Server Specify time in another timezoneSql Server 指定另一个时区的时间
【发布时间】:2015-06-18 15:41:23
【问题描述】:

我想编写一个查询,仅在英国下午 2 点之后才返回结果。我也知道美国东部时间到伦敦时间目前是五个小时的偏移量。我该怎么做?

select *
from table
where blah blah
and 2pm UK time < GETDATE()

【问题讨论】:

  • 您需要将 2pm UK(取决于 BST 或 GMT)转​​换为 UTC,然后将 UTC 中的当前时间与 UTC 中的 2pm GMT/BST 进行比较。这个答案应该对 stackoverflow.com/a/8038792/1370442 有所帮助 - 处理时间是一场噩梦!

标签: sql sql-server


【解决方案1】:

由于英国时区可能会受到夏令时的影响,我建议构建一个 DST 表并使用它来创建日期。

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

创建表:

CREATE TABLE dbo.TZCalendar
(
  [Year]        Int PRIMARY KEY,
  UTC_DST_Start SMALLDATETIME NOT NULL,
  UTC_DST_End   SMALLDATETIME NOT NULL,
  ET_DST_Start  AS CONVERT(SMALLDATETIME,DATEADD(HOUR, -4, UTC_DST_Start)),
  ET_DST_End    AS CONVERT(SMALLDATETIME,DATEADD(HOUR, -5, UTC_DST_End))
);

SET DATEFIRST 7;
;WITH cte(d,p) AS 
(
  -- all the years from 2000 through 50 years after the current year:
  SELECT TOP (YEAR(GETDATE())-2000+51) DATEADD(YEAR,number,'20000101'),
    CASE WHEN number < 7 THEN 1 ELSE 0 END -- year < 2007 = 1, else 0
    FROM [master].dbo.spt_values WHERE [type] = N'P' ORDER BY number
)
INSERT dbo.TZCalendar([Year],UTC_DST_Start,UTC_DST_End)
SELECT Year(d),
 -- First Sunday in April (< 2007) or second Sunday in March (>= 2007):
 DATEADD(HOUR, 7, DATEADD(DAY,(7-DATEPART(WEEKDAY,DATEADD(MONTH,2+p,d))+1)%7
    +(7*ABS(p-1)),DATEADD(MONTH,2+p,d))),
 -- Last Sunday in October (< 2007) or first Sunday in November (>= 2007):
 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;

接下来,我将创建一个函数来提取当前英国时间:

Create Function dbo.fnGetUKTime()
Returns DateTime
As Begin
    Declare @London DateTime = GetUTCDate()

    Declare @Offset Int = 0

    Select  @Offset = Case When @London Between UTC_DST_Start And UTC_DST_End Then 1 Else 0 End
    From    dbo.TZCalendar
    Where   Year = Year(@London)

    Set @London = DateAdd(Hour, @Offset, @London)

    Return @London
End
Go

然后,您可以在查询中引用它:

select *
from table
where blah blah
and DatePart(Hour, dbo.fnGetUKTime()) > 14

【讨论】:

  • 英国可以是格林威治标准时间或英国夏令时(夏令时),所以这可能会延迟 1 小时
  • 比如我现在在英国,现在是16:55,不是15:55!
  • @bUKaneer 更新了夏令时解决方案
  • 非常感谢您的详尽回答!效果很好!
【解决方案2】:

您可以使用datepart 来确定您服务器的当前日期时间偏移量(以分钟为单位):

select datepart(tz, sysdatetimeoffset())

例如,目前在英国(在 BST 期间),这给出了 60。

要确定您是在另一个时区的下午 2 点之前还是之后,您需要将当前时间与下午 2 点进行比较,加上您的偏移量,减去另一个时区的偏移量,例如,英国时间下午 2 点您当前的时区是:

select dateadd(minute, -<current uk offset>, dateadd(minute, datepart(tz, sysdatetimeoffset()), cast('14:00' as time)))

请注意,英国时区的当前偏移量在夏季为 60,在冬季为 0。如果您只对 GMT 而不是 BST 感兴趣,则可以省略这部分计算。

【讨论】:

  • 补充一下 - BST 从 3 月的最后一个星期日(IIRC,凌晨 1 点)开始,到 10 月的最后一个星期日结束,计算当前日期是否在 BST 范围内作为练习读者...
猜你喜欢
  • 2011-03-13
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2012-02-04
  • 1970-01-01
相关资源
最近更新 更多