Используйте MySQL для определения того, является ли сегодня днем ​​рождения пользователя

У меня есть дни рождения всех пользователей, хранящиеся как UNIXtimestamp, и я хочу каждый день отправлять электронные письма пользователям, имеющим день рождения в этот день.

Мне нужно сделать запрос MySQL, который будет получать все строки, содержащие день рождения на сегодняшний день.

Похоже, это должно быть довольно просто, но, возможно, я просто его преувеличиваю.

Ответ 1

Это должно работать:

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

Ответ 2

Вот ответ, который свойство учитывает високосные годы и всегда будет давать пользователям, чей день рождения 29 февраля, в то же время, что и 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'
        )

Ответ 3

Так как это все больше и больше становится вопросом с кодовым гольфом, здесь мой подход к решению этого вопроса, включая уход за високосными годами:

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 проверяет, есть ли сегодня день рождения. Второй - только те, чей день рождения - 29 февраля, только если текущий день равен последнему февралю февраля.

Примеры:

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'

Ответ 4

Я столкнулся с этой проблемой, и я просто использовал этот простой код, используя NOW();

$myquery = "SELECT username FROM $tblusers WHERE NOW() = bd";

Результаты сегодняшних дней рождения, после чего я работаю над отправкой писем моим пользователям в день их рождения.

Я храню своих пользователей bithdays, используя только DATE, поэтому у меня всегда есть yy:mm:dd, так что это работает как шарм, по крайней мере для меня, используя этот подход.

Ответ 5

Ответ ниже на самом деле не работает. Он не принимает во внимание тот факт, что год составляет 365,24 (високосный день, а затем) дней, поэтому фактическое сравнение с датой рождения пользователей сложно сказать по меньшей мере. Я оставляю это по историческим причинам.

Другие ответы должны работать, но если вы хотите небольшую оптимизацию, скажем, если есть много строк, вам, вероятно, лучше будет выражать запрос непосредственно в секундах секунд. Вы можете использовать отношения (слегка вовлеченные из-за учета часового пояса):

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

а затем выберите записи, где временная метка находится между этими значениями.

Ответ 6

Я отвел Сагги Малачи и продолжил, чтобы включить день рождения 29 февраля в дату 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

Здесь мой вклад

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)' возвращает 1 в високосные годы с 1-го марта 1-го числа будет дневной номер 61 и 0 в нормальные годы.

Отсюда просто вопрос о выделении дополнительного дня на вычисление "is-it-my-birthday-day".

Ответ 8

Наслаждайтесь:)

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;

Это дает вам день рождения человека, рассчитанный по текущему году. Тогда вы можете использовать его для других вычислений! Столбцы isBirthday28Feb и isThisYearLeap приведены только для иллюстрации решения.

Ответ 9

Это должно охватывать случаи високосного года и использует внутреннюю механику дат.

В основном это работает, добавляя годы между двумя датами к дате рождения и проверки на равенство с текущей датой:

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 */  

Ответ 10

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

Не могли бы вы просто выбрать все строки, соответствующие текущей дате? Вы также можете использовать функцию FROM_UNIXTIME() для преобразования из временной метки unix в Date:

mysql > SELECT FROM_UNIXTIME (1196440219);       - > '2007-11-30 10:30:19'

Это подтверждено документом http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_from-unixtime

Ответ 13

Вы можете использовать запрос ниже, если дата рождения хранится в таблице.

Сегодня День рождения:

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());