2013-12-12 17 views
0

我有一个带有生日字段的用户表,并且我正在尝试获取今天生日的所有用户ID。困难的部分是考虑国家和DST之间的时差。通过时差和DST获得世界各地的生日

这是我到目前为止有:

SELECT * 
FROM Users WITH(NOLOCK) 
WHERE MONTH(Birthday) = MONTH(GETDATE()) 
AND DAY(Birthday) BETWEEN DAY(GETDATE()) - 2 AND DAY(GETDATE()) + 2 

我包括 -/+ 2天,以确保我对谁可能提前或落后我们的服务器时间几个小时的生日。我不确定该从哪里出发。

我怎样才能确保我得到正确的用户?

编辑: 我正在使用SQL Server 2005,并根据他们的帐单国家知道用户的位置。

+1

你也存储用户的地理位置?如果您将GMT(格林威治标准时间)与用户位置结合使用,您可以在午夜时间将其发送给他们。 –

+0

你一定需要知道用户的地理位置或时区。你是否在你的用户表中存储了某个地方? – Shiva

+0

我们有一个法案国家,我们用它来确定他们的位置。有些也有账单状态,但不是全部。 –

回答

0

下面的示例创建一个以[tempdb中]是有48小时的日期的测试表。

如果我的服务器在GMT时间运行,我可以将存储在表格中的所有日期转换为GMT,方法是使用偏移量将常量归零。

-- Just playing around 
use tempdb; 
go 

-- A simple table with dates 
create table my_birthday 
(
    -- simple id 
    my_id int identity(1,1) primary key, 

    -- store date with offset 
    my_date datetimeoffset 
); 

-- Data with GMT offset 
declare @cnt int = -48; 
while @cnt < 49 
begin 
    insert into my_birthday (my_date) values (DATEADD(HH, [email protected], SYSDATETIMEOFFSET())); 
    set @cnt += 1; 
end; 

-- Pick todays data 
select * from my_birthday 
where datediff(d, my_date, switchoffset(CONVERT(datetimeoffset, '2013-12-12'), '+00:00')) = 0 

看看输出结果,我们在12-11上得到5个额外的日子,因为我在美国东部时区,在天结束时松了5天。但我们仍然只有24小时是正确的。

简而言之,您需要此解决方案的datetimeoffset数据类型和switchoffset()函数。

enter image description here

+0

用户的生日存储为没有时间戳或时区的日期,但这会使事情变得更容易。所以将它们转换为服务器时间没有任何好处。我能想到的唯一一个与他们的法案国家有关联的地方。 –

+0

添加一个带有datetimeoffset的附加列或表。按国家调整时区。那么你将成为当天的英雄! –