使用MySQL确定今天是否是用户的生日

时间:2010-02-07 21:19:22

标签: mysql timestamp unix-timestamp

我将所有用户的生日存储为UNIXtimestamp,并希望每天向当天有生日的用户发送电子邮件。

我需要创建一个MySQL查询,以获取今天包含生日的所有行。

看起来这应该相当简单,但也许我只是过于复杂了。

15 个答案:

答案 0 :(得分:19)

这应该有效:

   SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')

答案 1 :(得分:7)

这是一个答案,该财产考虑到闰年,并将始终为您提供2月29日生日与3月1日同时的用户。

SELECT * 
  FROM USERS
  WHERE 
     DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
     OR (
            (
                DATE_FORMAT(NOW(),'%Y') % 4 <> 0
                OR (
                        DATE_FORMAT(NOW(),'%Y') % 100 = 0
                        AND DATE_FORMAT(NOW(),'%Y') % 400 <> 0
                    )
            )
            AND DATE_FORMAT(NOW(),'%m-%d') = '03-01'
            AND DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'
        )

答案 2 :(得分:4)

由于这越来越成为一个代码高尔夫问题,这是我解决这个问题的方法,包括照顾闰年:

select * 
from user
where (date_format(from_unixtime(birthday),"%m-%d") = date_format(now(),"%m-%d"))
   or (date_format(from_unixtime(birthday),"%m-%d") = '02-29'
       and date_format('%m') = '02' 
       and last_day(now()) = date(now())
      );

说明:第一个where子句检查某人今天是否过生日。 第二个确保只选择那些生日是2月29日的人,只有当前一天等于2月的最后一天。

示例:

SELECT last_day('2009-02-01'); -- gives '2009-02-28'
SELECT last_day('2000-02-01'); -- gives '2009-02-29'
SELECT last_day('2100-02-01'); -- gives '2100-02-28'

答案 3 :(得分:2)

我遇到了这个问题,我只是使用NOW();

来使用这个简单的代码
$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";

结果是今天的生日,所以在那之后我在他们的生日那天向我的用户发送电子邮件。

我使用DATE存储我的用户bithdays所以我总是yy:mm:dd,所以这就像一个魅力,至少对我而言,使用这种方法。

答案 4 :(得分:2)

这应该涵盖闰年案例,并使用内部日期机制。

基本上它的工作原理是将两个日期之间的年份加到出生日期,并检查当前日期是否相等:

WHERE dob + INTERVAL (YEAR(CURDATE()) - YEAR(dob)) YEAR = CURDATE();

测试:

SELECT '2012-02-29' 
       + INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-29')) YEAR 
       = '2015-02-28'; /* 1, is birthday */

SELECT '2012-02-28' 
       + INTERVAL (YEAR('2015-02-28') - YEAR('2012-02-28')) YEAR  
       = '2015-02-28'; /* 1, is birthday */

SELECT '2012-02-28'
       + INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-28')) YEAR 
       = '2016-02-29'; /* 0, is NOT birthday  */

SELECT '2012-02-29'
       + INTERVAL (YEAR('2016-02-29') - YEAR('2012-02-29')) YEAR 
       = '2016-02-29'; /* 1, is birthday */  

答案 5 :(得分:1)

以下答案实际上并不奏效。它没有考虑到一年是365.24(昼夜不断)的日子这一事实,因此与用户生日的实际比较至少可以说是复杂的。我出于历史原因离开了。

  

其他答案应该有效,但是如果你想稍微优化一下,比如说有很多很多行,你可能最好直接在时间戳秒中表达查询。您可以使用关系(因为考虑了时区而略微参与):

today_starts = UNIX_TIMESTAMP(NOW()) - TIMESTAMPDIFF(SECOND, DATE(NOW()), NOW())
today_ends = today_starts + 86400
     

然后选择时间戳在这些值之间的记录。

答案 6 :(得分:1)

我接受了Saggi Malachi的回答并延长了包括2月29日到2月28日的生日,如果在那一年没有这样的日子。

SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = DATE_FORMAT(NOW(),'%m-%d')
UNION
SELECT * 
      FROM USERS
      WHERE 
         DATE_FORMAT(NOW(),'%Y')%4 != 0 AND DATE_FORMAT(NOW(),'%m-%d')='02-28' and DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') = '02-29'

答案 7 :(得分:1)

这是我的贡献

SELECT
  DAYOFYEAR(CURRENT_DATE)-(dayofyear(date_format(CURRENT_DATE,'%Y-03-01'))-60)=
  DAYOFYEAR(the_birthday)-(dayofyear(date_format(the_birthday,'%Y-03-01'))-60)
FROM
   the_table

比特'(dayofyear(date_format(current_date,'%Y-03-01')) - 60)'自3月1日起的闰年将返回1,年数为61,正常年份为0。

从这里开始,只需将额外的一天减去“生日那天” - 计算。

答案 8 :(得分:1)

享受:)

select p.birthday, 
CASE YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29 WHEN 0 THEN 1 ELSE 0 END as isBirthday29Feb,
CASE YEAR(now())%4  WHEN 0 THEN 1 ELSE 0 END as isThisYearLeap,
IF(YEAR(p.birthday)%4 + MONTH(p.birthday)-2 + dayofmonth(p.birthday)-29=0 AND YEAR(now())%4 != 0,
            DATE_ADD(DATE_ADD(p.birthday, INTERVAL 1  DAY), INTERVAL YEAR(NOW())-YEAR(p.birthday)  YEAR) ,
            DATE_ADD(p.birthday, INTERVAL YEAR(NOW())-YEAR(p.birthday)  YEAR)  
)as thisYearBirthDay
from person p;

这会根据当前年份计算出一个人的生日。 然后你可以用它来进行其他计算! 列isBirthday28FebisThisYearLeap仅用于说明解决方案。

答案 9 :(得分:1)

如果出生日期存储在表格中,您可以使用下面的查询。

今天生日:

select * from TABLENAME
 where DAY(FIELDNAME) = DAY(CURDATE())
   and MONTH(FIELDNAME) = MONTH(CURDATE());

昨天生日:

select * from TABLENAME
 where DAY(FIELDNAME) = DAY(DATE_ADD(CURDATE(), INTERVAL -1 DAY))
   and MONTH(FIELDNAME) = MONTH(CURDATE());

明天生日:

select * from TABLENAME
 where DAY(FIELDNAME) = DAY(DATE_ADD(CURDATE(), INTERVAL 1 DAY))
   and MONTH(FIELDNAME) = MONTH(CURDATE());

答案 10 :(得分:0)

set @now=now();
select * from user where (month(birthday) = month(@now) and day(birthday) = day(@now)) or
  (month(birthday) = 2 and day(birthday) = 29 and month(@now) = 2 and day(@now) = 28 and
  month(date_add(@now, interval 1 day)) = 3);

答案 11 :(得分:0)

难道你不能只选择与当天日期匹配的所有行吗?您还可以使用FROM_UNIXTIME()函数将unix时间戳转换为Date:

的MySQL&GT; SELECT FROM_UNIXTIME(1196440219);          - &GT; '2007-11-30 10:30:19'

这是从http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime

记录的

答案 12 :(得分:0)

答案 13 :(得分:0)

我接受了Saggi的回答,并考虑过修改它,以使其在接下来的7天显示生日,并注意到它也巧妙地解决了leap年的问题:)

SELECT * 
   FROM USERS
   WHERE 
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') >= DATE_FORMAT(NOW(),'%m-%d') AND
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') <  DATE_FORMAT(NOW()+INTERVAL 1 DAY,'%m-%d')

请注意,它不包含上限。对于leap年,没有任何东西介于“ 02-28”和“ 02-29”之间,但对于非-年,“ 02-29”介于“ 02-28”和“ 03-01”之间。


如果要在接下来的7天使用,请使用:

SELECT * 
   FROM USERS
   WHERE 
      DATE_FORMAT(FROM_UNIXTIME(birthDate),'%m-%d') BETWEEN
      DATE_FORMAT(NOW(),'%m-%d') AND DATE_FORMAT(NOW()+INTERVAL 7 DAY,'%m-%d')

答案 14 :(得分:-1)

您当前正在做的事情是确定今天是否是使用sql的用户生日,如果是,则分别发送愿望,有更好的方法来处理此问题。

  1. 在excel中提取愿望详细信息
  2. Wishing Application照顾其余的人

至少它只需要两件 excel文件,其中包含愿望详细信息(日期,姓名,电子邮件)和配置文件( application.properties ),就是这样,你很好。

此外,本地有各种options to run应用程序(命令行,前台,后台,泊坞窗,Windows Scheduler,Unix cron等)云。

应用程序为highly configurable,您可以配置各种详细信息,例如:

  • 工作簿加载选项
  • 带有愿望的图像选项。
  • SMTP配置
  • 其他应用程序级别的配置,例如何时发送愿望,迟来的愿望,日志记录等。

    免责声明:我是该应用程序的所有者

相关问题