Created
August 15, 2010 17:57
-
-
Save gavinblair/525746 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//ini_set("display_errors","on"); | |
//*************** | |
// | |
//Author: Andrew McClenaghan / Echidna Solutions Corp. | |
//Date: August 3, 2010 | |
// | |
//*************** | |
define('HOLIDAYS','2009-10-12|2009-12-25|2009-12-26|2010-01-01|2010-02-15|2010-04-02|2010-04-05|2010-05-24|2010-07-01|2010-08-02|2010-09-06');//the set of all stat holidays for the year | |
define('PICKUP_INTERVAL_IN_DAYS',8);//number of days in the pickup schedule | |
define('PICKUP_OUTPUTS',52);//number of pickup dates to output | |
define('INITIAL_PICKUP_DATE',"2009-10-05");//set to a valid garbage day for a zone, in this example zone c | |
//set initial date | |
$pickup_date = INITIAL_PICKUP_DATE; | |
for ($i=0;$i<PICKUP_OUTPUTS;$i++) //output a set number of pickup dates | |
{ | |
//save current pickup_date | |
$previous_pickup_date = $pickup_date; | |
//advance to next pickup date | |
$date_array = explode("-",$pickup_date); | |
$pickup_date=date("Y-m-d",mktime(0,0,0,$date_array[1],$date_array[2]+PICKUP_INTERVAL_IN_DAYS,$date_array[0])); | |
//loop and increment one day a time until a valid pickup_date is found | |
//a valid pickup day is one that is a weekday and not a holiday | |
while (!is_valid_pickup_date($pickup_date)) | |
{ | |
//advance one day | |
$pickup_date = increment_date($pickup_date); | |
} | |
//check to see if the past interval had a holiday // and if so advance an extra day for each holiday | |
$pickup_date = increment_date($pickup_date,number_of_holidays_in_previous_interval($pickup_date,$previous_pickup_date)); | |
//ensure once again that the adjusted pickup date is still valid | |
while (!is_valid_pickup_date($pickup_date)) | |
{ | |
//advance one day | |
$pickup_date = increment_date($pickup_date); | |
} | |
echo "<li>".date("l, M. d, Y",strtotime($pickup_date))."</li>"; | |
} | |
function number_of_holidays_in_previous_interval($pickup_date,$previous_pickup_date) | |
{//calculate the number of holidays that existed in a date interval and return the integer | |
$holiday_array = explode("|",HOLIDAYS); | |
$date_array = explode("-",$pickup_date); | |
$num_holidays = 0; | |
for($days=datediff("d",$previous_pickup_date,$pickup_date);$days>=0;$days--) | |
{ | |
$tempDate = date("Y-m-d",mktime(0,0,0,$date_array[1],$date_array[2]-$days,$date_array[0])); | |
if (in_array($tempDate,$holiday_array)) | |
$num_holidays++; | |
} | |
return $num_holidays; | |
} | |
function increment_date($pickup_date,$inc=1) | |
{//increment and return the date by $inc number of days | |
$date_array = explode("-",$pickup_date); | |
return date("Y-m-d",mktime(0,0,0,$date_array[1],$date_array[2]+$inc,$date_array[0])); | |
} | |
function is_holiday($pickup_date) | |
{//check to see if the date passed is a holiday | |
$holiday_array = explode("|",HOLIDAYS); | |
return in_array($pickup_date,$holiday_array); | |
} | |
function is_weekday($pickup_date) | |
{//check to see if the date passed is a weekday | |
$weekday_array = array(1,2,3,4,5); | |
return in_array(date("N",strtotime($pickup_date)),$weekday_array); | |
} | |
function is_valid_pickup_date($pickup_date) | |
{//is not a holiday? and is a weekday? | |
return (!is_holiday($pickup_date) && is_weekday($pickup_date)); | |
} | |
function datediff($interval, $datefrom, $dateto, $using_timestamps = false) { | |
// borrowed from somewhere.... need a reference | |
// $interval can be: | |
// yyyy - Number of full years | |
// q - Number of full quarters | |
// m - Number of full months | |
// y - Difference between day numbers | |
// (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".) | |
// d - Number of full days | |
// w - Number of full weekdays | |
// ww - Number of full weeks | |
// h - Number of full hours | |
// n - Number of full minutes | |
// s - Number of full seconds (default) | |
// | |
if (!$using_timestamps) { | |
$datefrom = strtotime($datefrom, 0); | |
$dateto = strtotime($dateto, 0); | |
} | |
$difference = $dateto - $datefrom; // Difference in seconds | |
switch($interval) { | |
case 'yyyy': // Number of full years | |
$years_difference = floor($difference / 31536000); | |
if (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom), date("j", $datefrom), date("Y", $datefrom)+$years_difference) > $dateto) { | |
$years_difference--; | |
} | |
if (mktime(date("H", $dateto), date("i", $dateto), date("s", $dateto), date("n", $dateto), date("j", $dateto), date("Y", $dateto)-($years_difference+1)) > $datefrom) { | |
$years_difference++; | |
} | |
$datediff = $years_difference; | |
break; | |
case "q": // Number of full quarters | |
$quarters_difference = floor($difference / 8035200); | |
while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($quarters_difference*3), date("j", $dateto), date("Y", $datefrom)) < $dateto) { | |
$months_difference++; | |
} | |
$quarters_difference--; | |
$datediff = $quarters_difference; | |
break; | |
case "m": // Number of full months | |
$months_difference = floor($difference / 2678400); | |
while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) { | |
$months_difference++; | |
} | |
$months_difference--; | |
$datediff = $months_difference; | |
break; | |
case 'y': // Difference between day numbers | |
$datediff = date("z", $dateto) - date("z", $datefrom); | |
break; | |
case "d": // Number of full days | |
$datediff = floor($difference / 86400); | |
break; | |
case "w": // Number of full weekdays | |
$days_difference = floor($difference / 86400); | |
$weeks_difference = floor($days_difference / 7); // Complete weeks | |
$first_day = date("w", $datefrom); | |
$days_remainder = floor($days_difference % 7); | |
$odd_days = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder? | |
if ($odd_days > 7) { // Sunday | |
$days_remainder--; | |
} | |
if ($odd_days > 6) { // Saturday | |
$days_remainder--; | |
} | |
$datediff = ($weeks_difference * 5) + $days_remainder; | |
break; | |
case "ww": // Number of full weeks | |
$datediff = floor($difference / 604800); | |
break; | |
case "h": // Number of full hours | |
$datediff = floor($difference / 3600); | |
break; | |
case "n": // Number of full minutes | |
$datediff = floor($difference / 60); | |
break; | |
default: // Number of full seconds (default) | |
$datediff = $difference; | |
break; | |
} | |
return $datediff; | |
} |
datediff('yyyy', 'today', 'tomorrow', false); => NAN... I would have expected 0
From http://londontrash.pbworks.com/Pickup-Date-Generator-Algorithm
An algorithm to determine if it is garbage day. In London garbage is picked up on an 8 day cycle, pausing for holidays. FYI, putting your garbage out on the wrong day results in a $500 fine!
The datediff function resembles this one: http://www.addedbytes.com/code/php-datediff-function/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What's this then?