[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Fmsystem-commits] [12060] API: add function to get business day for a timeperiod,
Sigurd Nes <=