fmsystem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fmsystem-commits] [12060] API: add function to get business day for a t


From: Sigurd Nes
Subject: [Fmsystem-commits] [12060] API: add function to get business day for a timeperiod
Date: Thu, 21 Aug 2014 12:40:25 +0000

Revision: 12060
          http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=12060
Author:   sigurdne
Date:     2014-08-21 12:40:25 +0000 (Thu, 21 Aug 2014)
Log Message:
-----------
API: add function to get business day for a timeperiod

Modified Paths:
--------------
    trunk/phpgwapi/inc/class.datetime.inc.php

Modified: trunk/phpgwapi/inc/class.datetime.inc.php
===================================================================
--- trunk/phpgwapi/inc/class.datetime.inc.php   2014-08-21 12:38:22 UTC (rev 
12059)
+++ trunk/phpgwapi/inc/class.datetime.inc.php   2014-08-21 12:40:25 UTC (rev 
12060)
@@ -988,4 +988,165 @@
                        }
                        return lang('Unknown');
                }
-       }
+
+               /**
+                * The function returns the no. of business days between two 
dates and it skips the holidays
+                * Example:
+                *      $holidays=array("2014-12-25","2014-12-26","2015-01-01");
+                *      echo getWorkingDays("2014-12-22","2015-01-02",$holidays)
+                *      will return 7
+                * @param string $start_date
+                * @param string $end_date
+                * @param array $holidays
+                * @return int
+                */
+               public static function get_working_days($start_date, $end_date, 
$holidays = array())
+               {
+                       if(!$start_date || !$end_date)
+                       {
+                               return;
+                       }
+
+                       /* do strtotime calculations just once */
+
+                       if (!ctype_digit($start_date))
+                       {
+                               $start_date = 
self::datetime_to_timestamp($start_date);
+                       }
+
+                       if (!ctype_digit($end_date))
+                       {
+                               $end_date = 
self::datetime_to_timestamp($end_date);
+                       }
+
+                       if($start_date > $end_date)
+                       {
+                               return;
+                       }
+
+                       if(!$holidays)
+                       {
+                               $holidays = 
self::get_holidays(date('Y',$end_date));
+                       }
+
+                       /*
+                        * The total number of days between the two dates. We 
compute the no. of seconds and divide it to 60*60*24
+                        * We add one to inlude both dates in the interval.
+                       */
+                       $days = ($end_date - $start_date) / 86400;
+
+                       $no_full_weeks = floor($days / 7);
+                       $no_remaining_days = fmod($days, 7);
+
+                       /* It will return 1 if it's Monday,.. ,7 for Sunday */
+                       $the_first_day_of_week = date("N", $start_date);
+                       $the_last_day_of_week = date("N", $end_date);
+
+                       /**
+                        * The two can be equal in leap years when february has 
29 days, the equal sign is added here
+                        * In the first case the whole interval is within a 
week, in the second case the interval falls in two weeks.
+                        */
+                       if ($the_first_day_of_week <= $the_last_day_of_week)
+                       {
+                               if ($the_first_day_of_week <= 6 && 6 <= 
$the_last_day_of_week)
+                               {
+                                       $no_remaining_days--;
+                               }
+                               if ($the_first_day_of_week <= 7 && 7 <= 
$the_last_day_of_week)
+                               {
+                                       $no_remaining_days--;
+                               }
+                       }
+                       else
+                       {
+                               /**
+                                * edit by Tokes to fix an edge case where the 
start day was a Sunday
+                                * and the end day was NOT a Saturday)
+                                *
+                                * the day of the week for start is later than 
the day of the week for end
+                                */
+                               if ($the_first_day_of_week == 7)
+                               {
+                                       /* if the start date is a Sunday, then 
we definitely subtract 1 day */
+                                       $no_remaining_days--;
+
+                                       if ($the_last_day_of_week == 6)
+                                       {
+                                               /* if the end date is a 
Saturday, then we subtract another day */
+                                               $no_remaining_days--;
+                                       }
+                               }
+                               else
+                               {
+                                       /**
+                                        * The start date was a Saturday (or 
earlier), and the end date was (Mon..Fri)
+                                        * so we skip an entire weekend and 
subtract 2 days
+                                        */
+                                       $no_remaining_days -= 2;
+                               }
+                       }
+
+                       /**
+                        * The no. of business days is: (number of weeks 
between the two dates) * (5 working days) + the remainder
+                        * february in none leap years gave a remainder of 0 
but still calculated weekends between first and last day, this is one way to 
fix it
+                        */
+                       $working_days = $no_full_weeks * 5;
+                       if ($no_remaining_days > 0 )
+                       {
+                         $working_days += $no_remaining_days;
+                       }
+
+                       //We subtract the holidays
+                       foreach($holidays as $holiday)
+                       {
+                               $time_stamp=strtotime($holiday);
+                               /*If the holiday doesn't fall in weekend*/
+                               if ($start_date <= $time_stamp && $time_stamp 
<= $end_date && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
+                               {
+                                       $working_days--;
+                               }
+                       }
+
+                       return $working_days;
+               }
+
+               /**
+                * Compile a list of holydays for a given year
+                * @staticvar array $holidays
+                * @param integer $year
+                * @return array $holidays for given year
+                */
+               public static function get_holidays($year = 0)
+               {
+                       static $holidays = array();
+                       $year = $year ? $year : date('Y');
+
+                       if(isset($holidays[$year]))
+                       {
+                               return $holidays[$year];
+                       }
+
+                       $easter_day = easter_days($year);
+                       $maundy_thursday = $easter_day -3;
+                       
+                       $holidays[$year] = array
+                       (
+                               date('Y-m-d', mktime(0, 0, 0, 12, 25, 
($year-1))),
+                               date('Y-m-d', mktime(0, 0, 0, 12, 26, 
($year-1))),
+                               date('Y-m-d', mktime(0, 0, 0, 1, 1, $year)),
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
( $maundy_thursday * 86400 ))),//Maundy Thursday
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
(( $maundy_thursday +1 ) * 86400))),//Good Friday
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
(( $easter_day +1 ) * 86400))),//Easter Monday
+                               date('Y-m-d', mktime(0, 0, 0, 5, 1, $year)),
+                               date('Y-m-d', mktime(0, 0, 0, 5, 17, 
$year)),//FIXME: Then Norwegian Constitution Day...
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
(( $easter_day + 39) * 86400))),//Ascension Day, 39 days after Easter Day
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
(( $easter_day + 49) * 86400))),//Whit Sunday, 49 days after Easter Day
+                               date('Y-m-d', (mktime(0, 0, 0, 3, 21, $year) + 
(( $easter_day + 50) * 86400))),//Whit monday, 50 days after Easter Day
+                               date('Y-m-d', mktime(0, 0, 0, 12, 25, ($year))),
+                               date('Y-m-d', mktime(0, 0, 0, 12, 26, ($year))),
+                       );
+
+                       return $holidays[$year];
+
+               }
+       }
\ No newline at end of file




reply via email to

[Prev in Thread] Current Thread [Next in Thread]