Welcome Guest ( Log In | Register )



 
Reply to this topicStart new topic
> Calendar And The Date () Function, Making Math Simple With Modular Arithmetic
Jared
post Apr 21 2008, 04:40 AM
Post #1


Member [ Level 1 ]
Group Icon

Group: [HOSTED]
Posts: 40
Joined: 17-April 08
Member No.: 29,853



In my days of calendar making I've encountered a few minor inconveniences. When you try to make a calendar, you have to find a few specific things: (1) the first day of the month, (2) how many days are in the month, and (3) what today's date is. The second and third ones are easy to find. Before we start making a calendar, though, let's set some ground rules:

CODE
define ('TS', time ());


Now we can find (2) and (3) from above:

CODE
$total_days = (int) date ('t', TS);
$todays_date = (int) date ('j', TS);


Now (1) is a different issue altogether. The way that I originally used to do it was to subtract a given date from the day of the week of that date and then add 1 and add 7 until you have a number between 0 and 6, inclusive.

CODE
$first_day = date ('w', TS) - date ('d', TS) + 1;
while ($first_day < 0) $first_day += 7;


The reason for having a while statement to do what could simply be done with the modulo operator (%) is because PHP is a little bit annoying when it comes to modulo. It seems that me that when you calculate a modulo, you should always have a positive number. So:

CODE
35 % 7 = 0
30 % 7 = 2
-35 % 7 = 0
-30 % 7 = 5


However, PHP does not see eye to eye with me on this one. Unfortunately, this is what PHP tells you:

CODE
35 % 7 = 0
30 % 7 = 2
-35 % 7 = 0
-30 % 7 = [b]-2[/b]


Now the tricky part here is that while 5 and -2 may be congruent modulo 7, they are not equal if you're not talking in modulo terms. So if we want to use modulo instead of the while statement and the 20th of April is on a Sunday then we have this:

CODE
$first_day = (date ('w', TS) - date ('d', TS) + 1) % 7;
$first_day = (0 - 20 + 1) % 7;
$first_day = -19 % 7;
$first_day = -5;


So we don't get a sensible value, as any sensible value would be positive. And the difficult part here is that you are not sure whether or not this value is negative. So if you want to use modulo, you still need an IF statement to decide whether or not to correct the negative.

But I finally came up with a better solution! Since the day of the week will never be less than 0 and the given date will never be greater than 31, the "potentially negative number" will never be less than 0 - 31 + 1 = -30. The next positive multiple of 7 larger than 30 is 35, so if we add 35 to this number it will not affect the modulo answer and it will ensure that the number is always positive.

So our equation changes from 0 - 31 + 1 to 0 - 31 + 1 + 35 = 0 - 31 + 36. So then now we can use modulo and not have to worry about IF statements or WHILE statement!

CODE
$first_day = (date ('w', TS) - date ('d', TS) + 36) % 7;


It's not like it's a particularly genius idea, but it certainly simplifies the calculation. And save a potential 4 while statements. So then if we want to turn this information into a calendar, here is a very simple script:

CODE
<?php

define ('TS', time ());

$first_day = (date ('w', TS) - date ('d', TS) + 36) % 7;
$total_days = (int) date ('t', TS);
$todays_date = (int) date ('j, TS);

echo '<table>' . "\r\n";
echo '<tr>' . "\r\n";
echo '<td align="center" colspan="7">' . date ('F Y', TS) . '</td>' . "\r\n";
echo '</tr>' . "\r\n";
echo '<tr>' . "\r\n";
echo '<td align="center">S</td>' . "\r\n";
echo '<td align="center">M</td>' . "\r\n";
echo '<td align="center">T</td>' . "\r\n";
echo '<td align="center">W</td>' . "\r\n";
echo '<td align="center">T</td>' . "\r\n";
echo '<td align="center">F</td>' . "\r\n";
echo '<td align="center">S</td>' . "\r\n";
echo '</tr>' . "\r\n";

for ($i = 0; $i < 6; $i++) {
    echo '<tr>' . "\r\n";

    for ($j = 0; $j < 7; $j++) {
        echo '<td align="center">' . (($t = $i * 7 + $j + 1 - $first_day) >= 1 && $t <= $total_days ? ($t == $todays_date ? '<b>' . $t . '</b>' : $t) : '&nbsp;') . '</td>' . "\r\n";
    }

    echo '</tr>' . "\r\n";
}

echo '</table>' . "\r\n";

?>


So there you have it! Any questions? Comments? Please post and let me know!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

Collapse

> Similar Topics

Topics Topics
  1. Stop anything from making it ur homepage!(52)
  2. (Nearly) Ultimate Music Posting Guide(11)
  3. Question About Asp Now() Function(6)
  4. Hack Websites(8)
  5. Finding Yahoo Account Creation Date(1)
  6. Alt Txt Tooltip Popups Over Text Links, How To Do?(11)
  7. PHP Tutorial: Form Verification And Simple Validation(12)
  8. Advice About Making A Text Based Game(9)
  9. Using The Php Mail() Function For Images Or Attachments(3)
  10. Programming In Glut (lesson 4)(7)
  11. Making A Turn Based Game Like Ogame(9)
  12. How To Boot A Pc From Your Usb Flashdisk(17)
  13. Include Function For Javascript(7)
  14. [photoshop] Making An Orb(1)
  15. Making Xp Starts 60% Faster(3)
  1. Very Simple Login-script(18)
  2. A Simple Register Script(3)
  3. Gimp: Working With Text(5)
  4. Need Help Making My Ftp Work(14)
  5. I Really Need Help(5)
  6. C/c++ -gdb Linux Debug Tool(0)
  7. Help With Making A Textbased Game(2)
  8. How To: Make A Simple Php Forum System(4)
  9. Simple Java Question(1)
  10. Help On Calc Date Issues !(4)
  11. Help With Making A Textbased Game(6)
  12. Date Timezones.(2)
  13. Making Xp Look Like Vista(3)


 



- Lo-Fi Version Time is now: 21st August 2008 - 11:16 PM