Hi
I would like to set up a php birthday reminder so that if users bdays are within the 7 days, it should display that the folllowing people celebrate their bday next week so far i have got to this stage, does any one have a better idea?

if(!empty($_POST)){
  
function birthday ($birthday){
    
list($year,$month,$day) = explode("-",$birthday);    
$year_diff  = date("Y") - $year;  
$month_diff = date("m") - $month; 
$day_diff   = date("d") - $day;
    
if ($day_diff < 0 || $month_diff < 0)     
$year_diff--;   
return $year_diff;
  
}

Any ideas will be wolcomed on how I can complete the rest of this code! all I would like is to see which friends or users have their bday in the next 7 days and their age if possible!!

Recommended Answers

All 15 Replies

1. Use code tags.
2. Use time stamps (functions like mktime, date, etc.) this will make comparing dates much easier.
3. Don't declare functions within control structure. Its just a bizarre practice.

Thanx I am not sure if I understand this!!!

If i use the mktime function for example this one!!

<?php
$tomorrow = mktime(0,0,0,date("m"),date("d")+1,date("Y"));
echo "Tomorrow is ".date("Y/m/d", $tomorrow);
This code will output = Tomorrow is 2009/02/13

So in order to get this dates from my database, and explode then what will i have to do, i know this is asking too much but could you plz demonstrate on a simple php code!!!

If you store the birthdays as timestamps rather than strings it is very easy. Something like this would do:

// $birthday has been selected from the database
if($birthday > time() && $birthday - time() <= (7 * 24 * 60 * 60))
{
  //birthday is within seven days
}

I have stored my birthdays as DATE type data 1985-02-14, I have got friends table, so how will my query be like in order to get those people in my database who's bdays are within a week? will this still work?

The database is not meant to be human readable, it is machine readable and efficient (we hope),
correct your database design to store dates as a timestamp, it is less overhead to rewrite the adduser script and do a tablewide update of existing records once than it is to constantly
read a record
explode it at '-'
convert it to a timestamp with mktime or strtotoime
compare the timestamp to the current timestamp
store the nickname
read the next record
print the stored names for a text stored date,
every record must be read and manipulated to collect a date range
TIMESTAMP is hugely faster, (uses less storage space smallint will hold it)
is easier to compare dates, extract a date range
its easier sql to select from tha database
set up the query

select nickname from table where birthday  BETWEEN CURDATE( )  AND  DATE_ADD(CURDATE(), INTERVAL +7 DAY);

to get a list of nicknames/loginnames of users with birthdays in the next seven days

How will i intergrade the "explode" function within my code, I mean how will i do this same as if i was to consider the 1st posting on the top of this page!

If you are too stubborn to accept that timestamps are in fact better or are too lazy to make the change, it would look like this:

$parts = explode("-",$birthday);
$yeah = $parts[0];
$month = $parts[1];
$day = $parts[2];
$birthday = mktime(0, 0, 0, $month, $day, $year);

Good thinking on doing it all within MySQL, bob.

fix the databse
then you dont have to
READ EVERY RECORD IN THE DATABASE
EXPLODE EVERY RECORD
MKTIME
Compare the generated timesatmp and then throw away all records that are not correct

WHAT IF:
you get bigger and there are 2-3 MILLION users at 1/1000 second for each record to make a happy birthday list, plus whatever other user tracking is going on, what are you going to do for the 33minutes - 45minutes your users are waiting for the page to display

$stamp = idate(z,Strtotime($birthday));
if ($stamp >= idate(z) and $stamp < (idate(z)+6)) {echo $nickname;}

for every record in the database

just for the hell of it I put 10000 random records in a database containing nickname and birthday
the sql based query prior took less than 1 second to execute 500 times and extract 500 sets of this weeks birthday

the php query took six seconds to run once and did extract the same three names

on my develpment box which is slower than a server

Fix The Database

in your input processigng you can still input the date as 1985-1-14, but if you explode it above and
or can input birthday as three datebits from drop down selects year month day

$birthday= mktime (0,0,0,$datebits[1],$datebits[2],$datebits[0],0);

and you can fix the table by

update table set birthday = %s , strtotime(birthday);

I havent checked what I just typed as the sql, its probably way wrong, using a php function in sql
but its read the birthday value, parse it to a

Hope something like this will work perfectly!! any more ideas or suggestions, really appreciate folks:

<?php
option 1 
//database connection

$parts = explode("-",$birthday); 
$year = $parts[0]; 
$month = $parts[1];
$day = $parts[2]; 
$birthday = mktime(0, 0, 0, $month, $day, $year);
     
//option 2
   
$datebits = explode('-', $birthday); 
$stamp = date(z,mktime (0,0,0,$datebits[1],$datebits[2],$datebits[0],0));
   
if ($stamp >= idate(z) and $stamp < (idate(z)+6)) {echo $nickname;}

$birthday=mysql_query("SELECT * FROM users WHERE birthday  BETWEEN CURDATE( ) AND  DATE_ADD(CURDATE(), INTERVAL +7 DAY);

$num_birthday = mysql_num_rows($birthdays);

if($birthday > time() && $birthday - time() <= (7 * 24 * 60 * 60))
  
{  
while ($row=mysql_fetch_ array($birthdays))
}
elseif ((strtotime($birthbday) - strtotime(now)) <= (7 * 24 * 60 * 60)
      
      {echo "this persons birthday is in the next 7 days";}

?>
$query = sprintf("UPDATE TABLE SET birthday = %s",
   strtotime($birthday));

that makes more sense

Hope something like this will work perfectly!! any more ideas or suggestions, really appreciate folks:

The wright brothers airplane still flies,
but they dont keep bolting new bits on it to make it useable
they mothballed it in a museum and build jumbo jets
bigger
faster
able to move hundreds of people
thousands of times further and
hundred times faster than the original planethis is a hint
ditch the biplane
build a jumbo
There would be less work in redoing the code, than always repairing it.

What about the next time you wish to add a feature.
it is real easy in timestamps to add StUfF,
"who's online"
"popular pages"
"most recently viewed'
without doing much programming work.

Thanks Guys!! really appreciate ur help ditch the biplane
build a jumbo nice 1.

Cheers

Bumped into this tread just now, and tried to build a nice jumbojet as adviced. But i can't put birthdays as timestamps in MySQL which are older than 1970. Am i wrong, or is there a nifty bypass?

I have stored the birthdates in the db in a YYYY-MM-DD format (just string) and want to get all birthdays from now to 7 days ahead.
Timestamps are no option as far as i know (see above post).
Here I found the solution to get it all by only using a MySQL-query:

SELECT * FROM `members` WHERE DATE_FORMAT(`dateofbirth`, '%m%d') >= DATE_FORMAT(NOW(), '%m%d') AND DATE_FORMAT(`dateofbirth`, '%m%d') <= DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%m%d') ORDER BY DATE_FORMAT(`dateofbirth`, '%m%d') ASC

This works simply and beautifully, without any heavy php-parsing.

I am so happy!

I have stored the birthdates in the db in a YYYY-MM-DD format (just string) and want to get all birthdays from now to 7 days ahead.
Timestamps are no option as far as i know (see above post).
Here I found the solution to get it all by only using a MySQL-query:

SELECT * FROM `members` WHERE DATE_FORMAT(`dateofbirth`, '%m%d') >= DATE_FORMAT(NOW(), '%m%d') AND DATE_FORMAT(`dateofbirth`, '%m%d') <= DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%m%d') ORDER BY DATE_FORMAT(`dateofbirth`, '%m%d') ASC

This works simply and beautifully, without any heavy php-parsing.

I am so happy!

If you are after optimized queries, another way is to save the day, month, and year as individual INT columns.

That way you can use the indexes on the INT columns, just as you would a timestamp, but allow any range of dates.

An example of a date range query, for birthdays within today (November 3rd) and the next 7 days.

SELECT * FROM users WHERE year = 2009 AND month = 11 AND day >= 3 AND day <= 9

or for two overlapping months, such as last week:

SELECT * FROM `users` WHERE 
(year = 2009 AND month = 10 AND day >=27)
OR
(year = 2009 AND month = 11 AND day <= 3)

A few things need to be calculated on the PHP side though, such as the number of days in the month and the overlaps between months. I wrote a class to handle this: http://code.google.com/p/php-calendar-class/

That would be more efficient then DATE_FORMAT() which does not make use of indexes.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.