MrFish Posted May 13, 2011 Share Posted May 13, 2011 If you need to find what day of the week it is, here is a handy function I've needed for a project where I need to write a calendar app. function getDayOfWeek($year, $month, $day){ //Don't know where this array of numbers came from but it was on wikipedia- they didn't explain it $months = array(0,3,3,6,1,4,6,2,5,0,3,5); $monthKey = $months[$month-1]; $cleanYear = $year % 100; $yearKey = floor($cleanYear/4); $century = $year - $cleanYear; $centuryKey = 2*(3-(substr($century, 0, 2) % 4)); $sum = $centuryKey + $yearKey + $cleanYear + $monthKey + $day; $dayOfWeek = $sum % 7; return $dayOfWeek;} Returns a number 0-6 (where 0 is Sunday and 6 is Saturday) $dayOfWeek = getDayOfWeek(2011, 5, 13);echo $dayOfWeek; //Prints 5 Here is how I've used it. $months = array(31,28,31,30,31,30,30,31,31,30,31,30,30);$month = date("m");$day = date("d");$numDays = $months[$month-1];if($month == 2){ if((date("y") % 4) == 0) $numDays = 29; }$startDay = getDayOfWeek(2011, $month, 1);$numRows = ceil(($startDay+$numDays)/7);$datesAdded = 0;$started = false;for($i = 0; $i < $numRows; $i++){ for($k = 0; $k < 7; $k++) { if(!$started) { if($k == $startDay) $started = true; else echo "<li><span></span></li>"; } if($started) { if($datesAdded < $numDays) { $class = ""; $datesAdded++; if($datesAdded == $day) $class = "event"; echo "<li><a href='#' class='$class'>$datesAdded</a></li>"; } else echo "<li><span></span></li>"; } } } Also I just noticed it's Friday the 13th so use this at your own risk. It might be a trojan... somehow...? Link to comment Share on other sites More sharing options...
ShadowMage Posted May 13, 2011 Share Posted May 13, 2011 That is way over-thinking this....How about:echo date('w', strtotime('5/12/2011'));or if you want a full textual representation:echo date('l', strtotime('5/12/2011'));One line... Link to comment Share on other sites More sharing options...
birbal Posted May 13, 2011 Share Posted May 13, 2011 Returns a number 0-6 (where 0 is Sunday and 6 is Saturday)If i am not missunderstanding it is like same as doing echo date('w'); Link to comment Share on other sites More sharing options...
MrFish Posted May 14, 2011 Author Share Posted May 14, 2011 If i am not missunderstanding it is like same as doing echo date('w');Not sure, but this isn't used to get the current day. This is used to get, say, the first day of the month. Which I guess there was already a function for that I didn't know about. At least with mine it doesn't use any IF statements. So even if it's already done I can still say mine is more efficient Link to comment Share on other sites More sharing options...
Synook Posted May 15, 2011 Share Posted May 15, 2011 As the other posters have alluded to, your function is exactly the same, in function, as: function getDayOfWeek($year, $month, $day){ return (int) date("w", mktime(0,0,0, $month, $day, $year));} Since this uses native functions, it is probably faster (not to mention, much shorter) (... and it doesn't use if statements, either). Don't forget, the date() function can parse arbitrary timestamps, not just for the current time. Link to comment Share on other sites More sharing options...
justsomeguy Posted May 15, 2011 Share Posted May 15, 2011 The date and mktime functions are both pretty powerful, so even when you're using them for basic things they still have a decent amount of overhead. Since the code given here really only uses arithmetic, where the only substantial function is substr, it is in fact faster. It's actually a little surprising how slow both date and mktime are. <?php$nr = 10000;$start = microtime(true);for ($i = 0; $i < $nr; $i++){ $first = getDayOfWeek1(2011, 5, 1);}$end = microtime(true);echo 'first test ran ' . $nr . ' iterations in ' . ($end - $start) . ' seconds, average of ' . (($end - $start)/$nr) . '<br>';$start = microtime(true);for ($i = 0; $i < $nr; $i++){ $first = getDayOfWeek2(2011, 5, 1);}$end = microtime(true);echo 'second test ran ' . $nr . ' iterations in ' . ($end - $start) . ' seconds, average of ' . (($end - $start)/$nr) . '<br>';function getDayOfWeek1($year, $month, $day){ return (int) date("w", mktime(0,0,0, $month, $day, $year));}function getDayOfWeek2($year, $month, $day){ //Don't know where this array of numbers came from but it was on wikipedia- they didn't explain it $months = array(0,3,3,6,1,4,6,2,5,0,3,5); $monthKey = $months[$month-1]; $cleanYear = $year % 100; $yearKey = floor($cleanYear/4); $century = $year - $cleanYear; $centuryKey = 2*(3-(substr($century, 0, 2) % 4)); $sum = $centuryKey + $yearKey + $cleanYear + $monthKey + $day; $dayOfWeek = $sum % 7; return $dayOfWeek;}?> first test ran 10000 iterations in 9.6887769699097 seconds, average of 0.00096887769699097second test ran 10000 iterations in 0.031805038452148 seconds, average of 3.1805038452148E-6Even when you only run mktime once:<?php$nr = 10000;$start = microtime(true);$time = mktime(0, 0, 0, 5, 1, 2011);for ($i = 0; $i < $nr; $i++){ $first = getDayOfWeek1($time);}$end = microtime(true);echo 'first test ran ' . $nr . ' iterations in ' . ($end - $start) . ' seconds, average of ' . (($end - $start)/$nr) . '<br>';$start = microtime(true);for ($i = 0; $i < $nr; $i++){ $first = getDayOfWeek2(2011, 5, 1);}$end = microtime(true);echo 'second test ran ' . $nr . ' iterations in ' . ($end - $start) . ' seconds, average of ' . (($end - $start)/$nr) . '<br>';function getDayOfWeek1($t){ return (int) date("w", $t);}function getDayOfWeek2($year, $month, $day){ //Don't know where this array of numbers came from but it was on wikipedia- they didn't explain it $months = array(0,3,3,6,1,4,6,2,5,0,3,5); $monthKey = $months[$month-1]; $cleanYear = $year % 100; $yearKey = floor($cleanYear/4); $century = $year - $cleanYear; $centuryKey = 2*(3-(substr($century, 0, 2) % 4)); $sum = $centuryKey + $yearKey + $cleanYear + $monthKey + $day; $dayOfWeek = $sum % 7; return $dayOfWeek;}?> first test ran 10000 iterations in 4.7254521846771 seconds, average of 0.00047254521846771second test ran 10000 iterations in 0.032104969024658 seconds, average of 3.2104969024658E-6The major downside with the code here is that it's difficult to understand and unexplained. The only comment says how they don't understand it. Link to comment Share on other sites More sharing options...
jeffman Posted May 15, 2011 Share Posted May 15, 2011 I'm sure the code originates as one of those algorithms that can be used in or out of a digital context. Sort of the way you can generate a perpetual calendar using paper and pencil. You just need to know the rules.At that level, it's kind of interesting. Link to comment Share on other sites More sharing options...
MrFish Posted May 16, 2011 Author Share Posted May 16, 2011 The major downside with the code here is that it's difficult to understand and unexplained. The only comment says how they don't understand it.The algorithm for calculating the day of the week can be found here.http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week1. Look up the 1900s in the centuries table: 02. Note the last two digits of the year: 823. Divide the 82 by 4: 82/4 = 20.5 and drop the fractional part: 204. Look up April in the months table: 65. Add all numbers from steps 1–4 to the day of the month (in this case, 24): 0+82+20+6+24=132.6. Divide the sum from step 5 by 7 and find the remainder: 132/7=18 remainder 67. Find the remainder in the days table: 6=Saturday.1. You can instead calculate this by taking the first 2 digits of the [century] and use it in this equation.[centuryKey] = 2(3-([century] mod 4))4. This wasn't explained anywhere or I just couldn't find it. So I used an array for this. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.