Feeling humble here (script is still buggy). Lot of lessons learned though. http://www.fuelefficiency.org/test/test6.php A lot of the echo output is put their temporarily to help debug. <form action="test6.php" method="post"> <fieldset><legend>Enter your birthday:</legend> <?php // Make the months array. $months = array (1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); // Make the months pull-down menu. echo '<select name="month">'; foreach ($months as $key => $value) { echo "<option value=\"$key\">$value</option>\n"; } echo '</select>'; // Make the days pull-down menu. echo '<select name="day">'; for ($day = 1; $day <= 31; $day++) { echo "<option value=\"$day\""; echo ">$day</option>\n"; } echo '</select>'; // Make the years pull-down menu. echo '<select name="year">'; for ($year = 1900; $year <= date ('Y'); $year++) { echo "<option value=\"$year\""; echo ">$year</option>\n"; } echo '</select><br>'; // Print the current day and time echo 'Today\'s date: '. date ('n, j, Y') . '<br>'; if (isset ($_POST['submitted'])) { $m = stripslashes(strip_tags($_POST['month'])); $d = stripslashes(strip_tags($_POST['day'])); $y = stripslashes(strip_tags($_POST['year'])); echo '<br>'; echo "You entered: $m, $d, $y <br>"; if (!checkdate($m, $d, $y) || //not valid date ($y == date('Y') && $m >date('n')) || // future (condition 1) ($y == date('Y') && $m == date('n') && $d > date('j')) // future (condition 2) ){ echo 'You entered an invalid date; please go back and re-enter the date.'; } else { echo 'Valid date<br><br>'; calcBday($m, $d, $y); } } //function calculates years, months, and days between past date and current date function calcBday($mo, $da, $yr){ // if GIVEN MONTH < CURRENT MONTH; echo YEARS... if ($mo <= date('n')){ //n stands for month $thisYear = date('Y'); $years = $thisYear - $yr; echo "You are $years years, "; // ...if GIVEN DAY <= CURRENT DAY; echo MONTHS, DAYS if ($da <= date('j')){ //j stands for day of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth - $mo; echo "$months months"; //...echo DAYS $thisDay = date('j'); $days = $thisDay - $da; echo ", and $days"; echo ($days > 1) ? " days old." : "day old."; echo '<br>You where born on a day less than this month\'s day <br>(theirfore the days in the month do not effect the calculation)'; } // ...if GIVEN DAY > CURRENT DAY; echo MONTHS, DAYS if ($da > date('j')){ //j stands for DAY of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth - $mo - 1; echo "$months months"; //...echo DAYS $thisDay = date('j'); //30 days have sept, april, june, and nov.. if ($mo==4 || $mo==6 || $mo==9 || $mo==11) { $DaysInGivenMonth_Minus_GivenDay = 30-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 30.'"; } //...all the rest have 31 except for... if ($mo==1 || $mo==3 || $mo==5 || $mo==7 || $mo==8 || $mo==10 || $mo==12){ $DaysInGivenMonth_Minus_GivenDay = 31-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 31.'"; } //february has 28, except on leap years it has 29; //leap year in all recent are the years dividsible by 4 (except 1700, 1800, 1900, and 2100 excluded) if ($mo == 2) { $yrsDivFour = $yr/4; $roundedYrsDivFour = round($yrsDivFour, 0); //IF: February leap year, ELSE: February not leap year if ($roundedYrsDivFour == $yrsDivFour && $yr!=1700 && $yr!=1800 && $yr!=1900 && $yr!=2100) { //1700, 1800, 1900, and 2100 are axceptions; not leap years $DaysInGivenMonth_Minus_GivenDay = 29-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo '<br>You where born in February on a leap year.<br>'; } else { $DaysInGivenMonth_Minus_GivenDay = 28-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born in February, but not in a Leap Year<br>"; } } } }// *END*: GIVEN MONTH < CURRENT MONTH; // if GIVEN MONTH > CURRENT MONTH, echo YEARS, MONTHS, DAYS if ($mo > date('n')){ $thisYear = date('Y'); $years = $thisYear - $yr -1; echo "You are $years years,"; // ...if GIVEN DAY <= CURRENT DAY; echo MONTHS, DAYS if ($da <= date('j')){ //j stands for day of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth + 13- $mo; echo " $months months"; //...echo DAYS $thisDay = date('j'); $days = $thisDay - $da; echo ", and $days"; echo ($days > 1) ? " days old." : "day old."; } // ...if GIVEN DAY > CURRENT DAY; echo MONTHS, DAYS if ($da > date('j')){ //j stands for DAY of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth + 12- $mo; echo " $months months"; //...echo DAYS $thisDay = date('j'); //30 days have sept, april, june, and nov.. if ($mo==4 || $mo==6 || $mo==9 || $mo==11) { $DaysInGivenMonth_Minus_GivenDay = 30-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 30.'"; } //...all the rest have 31 except for... if ($mo==1 || $mo==3 || $mo==5 || $mo==7 || $mo==8 || $mo==10 || $mo==12){ $DaysInGivenMonth_Minus_GivenDay = 31-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 31.'"; } //february has 28, except on leap years it has 29; //leap year in all recent are the years dividsible by 4 (except 1700, 1800, 1900, and 2100 excluded) if ($mo == 2) { $yrsDivFour = $yr/4; $roundedYrsDivFour = round($yrsDivFour, 0); //IF: February leap year, ELSE: February not leap year if ($roundedYrsDivFour == $yrsDivFour && $yr!=1700 && $yr!=1800 && $yr!=1900 && $yr!=2100) { //1700, 1800, 1900, and 2100 are axceptions; not leap years $DaysInGivenMonth_Minus_GivenDay = 29-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo '<br>You where born in February on a leap year.<br>'; } else { $DaysInGivenMonth_Minus_GivenDay = 28-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born in February, but not in a Leap Year<br>"; } } } } // given month > current month }//end function ?> </fieldset></p> <div align="center"><input type="submit" name="submitted" value="Calculate my Birthday" /></div> </form> PHP:
That seems pretty fun, though I think there's an error in it.: See how it says im 17 without a month and 16 days. That would put my birthday on septerber30th/october 1st. Today's date: 8, 15, 2007 You entered: 8, 30, 1990 Valid date You are 17 years, -1 months, and 16 days old. You where born on a day greater than this month's day (theirfore the days in the month do effect the calculation) The number of day's in your birth month where 31.' Code (markup):
While learning there is a point to writing every single character, the knowledge tends to stick a little better when you do it the hard way. As for editors my current favorite is Eclipse with a php add-on. It has some flaws as does most editors I've ever used (about 20 years of programming, 10 proffesionally) but there are macros for faster typing and good support for html and such. And even though I've programmed for two decades I still type most of the code character by character (experienced programmers learn to mistrust copy/paste) and I still write "Hello World" like programs in every new programming language I learn.
Today's date: 8, 16, 2007 You entered: 9, 11, 1970 Valid date You are 36 years, 12 months, and 5 days old. No I'm not.
I may be a newb, but I'm a persistent newb. Any persistent bugs? http://www.fuelefficiency.org/test/test6.php <form action="test6.php" method="post"> <fieldset><legend>Enter your birthday:</legend> <?php // Make the months array. $months = array (1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); // Make the months pull-down menu. echo '<select name="month">'; foreach ($months as $key => $value) { echo "<option value=\"$key\">$value</option>\n"; } echo '</select>'; // Make the days pull-down menu. echo '<select name="day">'; for ($day = 1; $day <= 31; $day++) { echo "<option value=\"$day\""; echo ">$day</option>\n"; } echo '</select>'; // Make the years pull-down menu. echo '<select name="year">'; for ($year = 1900; $year <= date ('Y'); $year++) { echo "<option value=\"$year\""; echo ">$year</option>\n"; } echo '</select><br>'; // Print the current day and time echo 'Today\'s date: '. date ('n, j, Y') . '<br>'; if (isset ($_POST['submitted'])) { $m = stripslashes(strip_tags($_POST['month'])); $d = stripslashes(strip_tags($_POST['day'])); $y = stripslashes(strip_tags($_POST['year'])); echo '<br>'; echo "You entered: $m, $d, $y <br>"; if (!checkdate($m, $d, $y) || //not valid date ($y == date('Y') && $m >date('n')) || // future (condition 1) ($y == date('Y') && $m == date('n') && $d > date('j')) // future (condition 2) ){ echo 'You entered an invalid date; please go back and re-enter the date.'; } else { echo 'Valid date<br><br>'; calcBday($m, $d, $y); } } //function calculates years, months, and days between past date and current date function calcBday($mo, $da, $yr){ // if GIVEN MONTH < CURRENT MONTH; echo YEARS... if ($mo < date('n')){ //n stands for month $thisYear = date('Y'); $years = $thisYear - $yr; echo "You are $years years, "; // ...if GIVEN DAY <= CURRENT DAY; echo MONTHS, DAYS if ($da <= date('j')){ //j stands for day of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth - $mo; echo "$months months"; //...echo DAYS $thisDay = date('j'); $days = $thisDay - $da; echo ", and $days"; echo ($days > 1) ? " days old." : "day old."; echo '<br>You where born on a day less than this month\'s day <br>(theirfore the days in the month do not effect the calculation)'; } // ...if GIVEN DAY > CURRENT DAY; echo MONTHS, DAYS if ($da > date('j')){ //j stands for DAY of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth - $mo - 1; echo "$months months"; //...echo DAYS $thisDay = date('j'); //30 days have sept, april, june, and nov.. if ($mo==4 || $mo==6 || $mo==9 || $mo==11) { $DaysInGivenMonth_Minus_GivenDay = 30-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 30.'"; } //...all the rest have 31 except for... if ($mo==1 || $mo==3 || $mo==5 || $mo==7 || $mo==8 || $mo==10 || $mo==12){ $DaysInGivenMonth_Minus_GivenDay = 31-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 31.'"; } //february has 28, except on leap years it has 29; //leap year in all recent are the years dividsible by 4 (except 1700, 1800, 1900, and 2100 excluded) if ($mo == 2) { $yrsDivFour = $yr/4; $roundedYrsDivFour = round($yrsDivFour, 0); //IF: February leap year, ELSE: February not leap year if ($roundedYrsDivFour == $yrsDivFour && $yr!=1700 && $yr!=1800 && $yr!=1900 && $yr!=2100) { //1700, 1800, 1900, and 2100 are axceptions; not leap years $DaysInGivenMonth_Minus_GivenDay = 29-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo '<br>You where born in February on a leap year.<br>'; } else { $DaysInGivenMonth_Minus_GivenDay = 28-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born in February, but not in a Leap Year<br>"; } } } }// *END*: GIVEN MONTH < CURRENT MONTH; // if GIVEN MONTH > CURRENT MONTH, echo YEARS, MONTHS, DAYS if ($mo > date('n')){ $thisYear = date('Y'); $years = $thisYear - $yr -1; echo "You are $years years,"; // ...if GIVEN DAY <= CURRENT DAY; echo MONTHS, DAYS if ($da <= date('j')){ //j stands for day of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth + 12- $mo; echo " $months months"; //...echo DAYS $thisDay = date('j'); $days = $thisDay - $da; echo ", and $days"; echo ($days > 1) ? " days old." : "day old."; } // ...if GIVEN DAY > CURRENT DAY; echo MONTHS, DAYS if ($da > date('j')){ //j stands for DAY of month //...echo MONTHS $thisMonth = date('n'); $months = $thisMonth + 11- $mo; echo " $months months"; //...echo DAYS $thisDay = date('j'); //30 days have sept, april, june, and nov.. if ($mo==4 || $mo==6 || $mo==9 || $mo==11) { $DaysInGivenMonth_Minus_GivenDay = 30-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 30.'"; } //...all the rest have 31 except for... if ($mo==1 || $mo==3 || $mo==5 || $mo==7 || $mo==8 || $mo==10 || $mo==12){ $DaysInGivenMonth_Minus_GivenDay = 31-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 31.'"; } //february has 28, except on leap years it has 29; //leap year in all recent are the years dividsible by 4 (except 1700, 1800, 1900, and 2100 excluded) if ($mo == 2) { $yrsDivFour = $yr/4; $roundedYrsDivFour = round($yrsDivFour, 0); //IF: February leap year, ELSE: February not leap year if ($roundedYrsDivFour == $yrsDivFour && $yr!=1700 && $yr!=1800 && $yr!=1900 && $yr!=2100) { //1700, 1800, 1900, and 2100 are axceptions; not leap years $DaysInGivenMonth_Minus_GivenDay = 29-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo '<br>You where born in February on a leap year.<br>'; } else { $DaysInGivenMonth_Minus_GivenDay = 28-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born in February, but not in a Leap Year<br>"; } } } } // given month > current month // if GIVEN MONTH = CURRENT MONTH, echo YEARS, MONTHS, DAYS if ($mo == date('n')){ $thisYear = date('Y'); if ($da > date('j')){ $years = $thisYear - $yr -1; echo "You are $years years, 11 months"; //...echo DAYS $thisDay = date('j'); //30 days have sept, april, june, and nov.. if ($mo==4 || $mo==6 || $mo==9 || $mo==11) { $DaysInGivenMonth_Minus_GivenDay = 30-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 30.'"; } //...all the rest have 31 except for... if ($mo==1 || $mo==3 || $mo==5 || $mo==7 || $mo==8 || $mo==10 || $mo==12){ $DaysInGivenMonth_Minus_GivenDay = 31-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born on a day greater than this month's day <br>(theirfore the days in the month do effect the calculation)<br> The number of day's in your birth month where 31.'"; } //february has 28, except on leap years it has 29; //leap year in all recent are the years dividsible by 4 (except 1700, 1800, 1900, and 2100 excluded) if ($mo == 2) { $yrsDivFour = $yr/4; $roundedYrsDivFour = round($yrsDivFour, 0); //IF: February leap year, ELSE: February not leap year if ($roundedYrsDivFour == $yrsDivFour && $yr!=1700 && $yr!=1800 && $yr!=1900 && $yr!=2100) { //1700, 1800, 1900, and 2100 are axceptions; not leap years $DaysInGivenMonth_Minus_GivenDay = 29-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo '<br>You where born in February on a leap year.<br>'; } else { $DaysInGivenMonth_Minus_GivenDay = 28-$da; $days = $thisDay + $DaysInGivenMonth_Minus_GivenDay; //<<<<<<<<<<<<< echo ", and $days"; echo ($days > 1) ? " days old." : " day old."; echo "<br>You where born in February, but not in a Leap Year<br>"; } } } if ($da <= date('j')){ $years = $thisYear - $yr; $thisDay = date('j'); $days = $thisDay - $da; echo "You are $years years, 0 months, and $days days old"; } } }//end function ?> </fieldset></p> <div align="center"><input type="submit" name="submitted" value="Calculate my Birthday" /></div> </form> PHP: lol, thirty days have september, april, june and ... (I didn't forget leap years)
Passed my test (pay me and I'll test more than my own birthday ). Looking at your code made my fingers itch. I'll tell you why: There's a good principle in programming called DRY - "Don't Repeat Yourself". Quickly scanning your code I counted 13 places where you print "and X days..." You should ideally be able to remove all of them and replace them with a single instance of printing. This will (or should at least) make the code far easier to read, bugfix, update, translate... you get the point. I further feel that the algorithm could probably be written with less code. Here's my take on the algo. 1. Calculate the difference between the years, the months and the days (individually). 2. If day-diff is negative decrease month-diff by one 3. If month-diff is negative decrease year-diff by one 4. If day-diff was negative calculate days with special care. Have'nt tried this one, it probably fails in some case but it should be quite easy to work around (this is my intuitive feeling for the problem, I'm wrong about these kinds of problems more often than I'd like to admit).
Perrow, I agree their is a better way, I was kind of thinking it should be more like a cars odometer, but you articulated it better. I also thought I should try my hand at a flow chart to organize my thoughts better. Towards the end I was just copying, pasting, and hacking stuff together to get the bugs out; i.e. a lot of redundancy and sloppiness. I'm still a newb, but I'm very happy with my progress this week. Thanks Perrow, ecentrickNick and everyone else who helped. Unfortunately today is day 6 for me and my mind is becoming consumed with school transcripts, calculus, physics, etc. for a few days.
I don't know if I'm late or not, Roger, but I sent you a PM and it might help you (or might not). I sent it to you in a PM because it's a PHP tutorial I'm still working on and don't want it to be public yet.