Skip to content

Instantly share code, notes, and snippets.

@clrockwell
Last active June 27, 2016 21:55
Show Gist options
  • Save clrockwell/c9b2a7b647087d541900b08ac14dfdc4 to your computer and use it in GitHub Desktop.
Save clrockwell/c9b2a7b647087d541900b08ac14dfdc4 to your computer and use it in GitHub Desktop.
<?php
/**
* @file
* Functions to build working hours
* @
*/
define('WORKING_REPORTS_MONTH_YEAR_START', 7); // July
define('WORKING_REPORTS_MONTH_YEAR_END', 6); // June
define('WORKING_REPORTS_HOURS_IN_DAY', 8);
function cela_reports__working_hours__get_cela_starting_year() {
$now = new DateTime();
return WORKING_REPORTS_MONTH_YEAR_START <= (int)$now->format('m')
? (int)$now->format('Y')
: (int)$now->format('Y')-1;
}
function cela_reports__working_hours__get_cela_ending_year() {
$now = new DateTime();
return WORKING_REPORTS_MONTH_YEAR_END >= (int)$now->format('m')
? (int)$now->format('Y')
: (int)$now->format('Y')+1;
}
/**
* Get the working year months (we operate July - June)
* For now this is hardcoded in constants, doubtful to ever change
*
* @return array of months and years
*/
function cela_reports__working_hours__operating_months($starting_year, $ending_year) {
$start = new DateTime($starting_year . '-' . WORKING_REPORTS_MONTH_YEAR_START . '-01');
$end = new DateTime($ending_year . '-' . WORKING_REPORTS_MONTH_YEAR_END);
$end->modify('+1 Month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$working_months = [];
foreach ($period as $dt) {
$working_months[] = [
'year' => $dt->format('Y'),
'month' => $dt->format('m'),
];
}
return $working_months;
}
/**
* Get the days in month
* Right now, a simple wrapper for cal_days_in_month().
* @see http://php.net/manual/en/function.cal-days-in-month.php
*
* @param int $month
* @param int $year
*
* @return The length in days of the selected month in the given calendar
*/
function cela_reports__working_hours__days_month($month, $year) {
return cal_days_in_month(CAL_GREGORIAN, $month, $year);
}
/**
* Get count of holidays in a given month
* Holidays are a content type with a date field
*
* @param int $month The month
* @param int $year The year
*/
function cela_reports__working_hours__holidays_month_count($month, $year) {
return count(cela_reports__working_hours__holidays_month($month, $year));
}
/**
* Get all holidays in a month
*
* @param int $month The month
* @param int $year The year
*
* @return array
*/
function cela_reports__working_hours__holidays_month($month, $year) {
$holidays = db_select('field_revision_field_event_dates', 'f')
->fields('f', array('field_event_dates_value'))
->condition('entity_type', 'event')
->condition('bundle', 'holiday')
->execute()
->fetchAll();
$holidays_this_month = array_filter($holidays, function($item) use ($month, $year) {
return date('Y-n', strtotime($item->field_event_dates_value)) == date('Y-n', strtotime($year . '-' . $month));
});
return $holidays_this_month;
}
/**
* Get count of certain days in month
* Just a wrapper around the single function
* @param array of integers $days ISO-8601 numeric representation of the day of the week
* 1 = Monday
* 2 = Tuesday
* ...
* 6 = Saturday
* 7 = Sunday
* @param int $month The Month
* @param int $year The Year
*/
function cela_reports__working_hours__day_count_multiple($days, $month, $year) {
$day_count = 0;
array_walk($days, function($day) use ($month, $year, &$day_count) {
$day_count += cela_reports__working_hours__day_count_single($day, $month, $year);
});
return $day_count;
}
/**
* Get count single day occurences in month
*
* @param int $day The day
* @param string $month The month
* @param string $year The year
*
* @return integer ( description_of_the_return_value )
*/
function cela_reports__working_hours__day_count_single($day, $month, $year) {
$from = new DateTime($year . '-' . $month . '-01');
$to = new DateTime($year . '-' . $month . '-' . date('t', strtotime($year . '-' . $month)));
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$periods = new DatePeriod($from, $interval, $to);
$day_count = 0;
foreach ($periods as $period) {
if ($period->format('N') == (int)$day) {
$day_count++;
}
}
return $day_count;
}
/**
* Utility function for getting the number of non-working days
* for a month
*
* @param int $month The month
* @param int $year The year
*
* @return the sum of cela_reports__working_hours__day_count_multiple()
* (using Saturday/Sunday) and cela_reports__working_hours__holidays_month_count()
*/
function cela_reports__working_hours__non_working_days_count($month, $year) {
return (int) cela_reports__working_hours__day_count_multiple([6,7], $month, $year)
+ (int) cela_reports__working_hours__holidays_month_count($month, $year);
}
/**
* Utilty function for getting total working days
* Which is total number of days in month - non-working days
*/
function cela_reports__working_hours__working_days_count($month, $year) {
return (int)cela_reports__working_hours__days_month($month, $year)
- (int)cela_reports__working_hours__non_working_days_count($month, $year);
}
/**
* Utility function for getting total working hours for month
* Is cela_reports__working_hours__working_days_count * 8;
*/
function cela_reports__working_hours__working_hours_month($month, $year) {
return (int)cela_reports__working_hours__working_days_count($month, $year) * WORKING_REPORTS_HOURS_IN_DAY;
}
/**
* Utility function to build entire report.
* To be used as a table, with:
* - rows = months of current operating years
* - columns
* - Days
* - Holidays
* - Saturdays
* - Sundays
* - Total non-working days
* - Total working days
* - Total working hours
*/
function cela_reports__working_hours__monthly_report() {
$start_year = cela_reports__working_hours__get_cela_starting_year();
$end_year = cela_reports__working_hours__get_cela_ending_year();
$months = cela_reports__working_hours__operating_months($start_year, $end_year);
$report = [];
foreach ($months as $month) {
$textual_month = date('F', strtotime($month['year'] . '-' . $month['month']));
$report[$textual_month] = [
'days' => cela_reports__working_hours__days_month($month['month'], $month['year']),
'holidays' => cela_reports__working_hours__holidays_month_count($month['month'], $month['year']),
'saturdays' => cela_reports__working_hours__day_count_single(6, $month['month'], $month['year']),
'sundays' => cela_reports__working_hours__day_count_single(7, $month['month'], $month['year']),
'total non-work days' => cela_reports__working_hours__non_working_days_count($month['month'],
$month['year']),
'total working days' => cela_reports__working_hours__working_days_count($month['month'], $month['year']),
'total working hours' => cela_reports__working_hours__working_hours_month($month['month'], $month['year'])
];
}
return $report;
}
@travisaxton
Copy link

I would have written this in one line. Nice try though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment