#native_company# #native_desc#
#native_cta#

Advance date to the next X business days.

By Maresa Nirwan
on November 18, 2002

Version: 0.9

Type: Function

Category: Calendars/Dates

License: GNU General Public License

Description: Takes a date, and advance it to the next X business days.
If the date falls on weekend, then it’ll advance from the next Monday.
For example, you have 3 processing days for all orders:
Given Order Date: 2002-12-31
Script will return Ship date: 2003-1-3
@param $orderDate the starting date in the form YYYY-MM-DD or YYYY/MM/DD

<?php
/**
   By Maresa Nirwan ([email protected])
   written: 2002-11-17
   Ver: 0.9
   
   Takes a date, and advance it to the next $ORDER_PROCESSING_DAYS business days.
   If the date falls on weekend, then it'll advance from the next Monday.
   For example, you have 3 processing days for all orders:
   Given Order Date: 2002-12-31
   Script will return Ship date: 2003-1-3
   @param $orderDate the starting date in the form YYYY-MM-DD or YYYY/MM/DD
*/
 
function generateShipDate ($orderDate = "")
{
   /**
      If you don't have global config file, use this instead
      $ORDER_PROCESSING_DAYS = X;
      where X is the number of business days
   */
   global $ORDER_PROCESSING_DAYS;

   if ($orderDate == "")
      $orderDate = date("Y-m-d");

   if (strpos($orderDate, "-"))
      $charDelim = "-";
   else if (strpos($orderDate, "/"))
      $charDelim = "/";

   list($year, $month, $date) = explode($charDelim, $orderDate);

   /**
      Change 1990 to earliest year you want
   */
   if ($year <= 1990 || $month <= 0 || $month > 12 || $date <= 0 || $date > 31)
   {
      $year  = date("Y");
      $month = date("m");
      $date  = date("d");
   }

   $a=(int)((14-$month) / 12);
   $y=$year-$a;
   $m=$month + (12*$a) - 2;

   /**
      The following line will return days in week as follows:
      0 = Sunday
      1 = Monday
      ...
      6 = Saturday
   */
   $dayName=($date + $y + (int)($y/4) - (int)($y/100) + (int)($y/400) + (int)((31*$m)/12)) % 7;

   /**
      If the date falls on weekend, add 1 or 2 days to $ORDER_PROCESSING_DAYS
      because we don't consider weekend as business day.
      Add 1 to $ORDER_PROCESSING_DAYS if the date is a Sunday
      Add 2 to $ORDER_PROCESSING_DAYS if the date is a Saturday
   */
   if ($dayName == 6)
   {
      $processingDays = $ORDER_PROCESSING_DAYS + 2;
      $dayName = 1;
   }
   else if ($dayName == 0)
   {
      $processingDays = $ORDER_PROCESSING_DAYS + 1;
      $dayName = 1;
   }
   else
      $processingDays = $ORDER_PROCESSING_DAYS;

   $actualProcessingDays = $processingDays + ((int)(($processingDays - 1) / 5)) * 2;

   $date = $date + $actualProcessingDays;

   do
   {
      switch ($month)
      {
         case 4:
         case 6:
         case 9:
         case 11:
            $maxDaysInMonth = 30;
            break;
         case 2: // February Check
            if (($year/4)==(floor($year/4)))
            {
               if (($year/100)==(floor($year/100)))
               {
                  if (($year==1600) or ($year==2000) or ($year==2400))
                     $maxDaysInMonth = 29;
                  else
                     $maxDaysInMonth = 28;
               } else
                  $maxDaysInMonth = 29;
            } else
               $maxDaysInMonth = 28;
            break;
         default:
            $maxDaysInMonth = 31;
      }
      if ($date <= $maxDaysInMonth)
         break;
      else
      {
         $date = $date - $maxDaysInMonth;
         if ($month == 12)
         {
            $month = 1;
            $year++;
         }
         else
            $month++;
      }
   } while ($date > $maxDaysInMonth);

   return "$year-$month-$date";
}
?>