Since I work on our HR team at Automattic, sometimes I need to write code dealing with payroll. When someone starts or leaves we have to pay them for a partial period, which is based on the number of week days. Originally I wrote a simple function, but I set out to make it more useable. Here is what I came up with…
/**
* Counts the days (optionally limited by type of day) between (inclusive) two dates.
*
* @param string $start_date First day (Y-m-d format).
* @param string $end_date Last day (Y-m-d format).
* @param array $types Optional. Types of days to count. Default to all types
*
* @return int Number of days matching the $types.
*/
function get_days_between_dates( $start_date, $end_date, $types = array() ) {
$count = 0;
$included_day_type_indexes = array();
if ( empty( $types ) ) {
$included_day_type_indexes = range( 1, 7 );
} else {
foreach ( $types as $type ) {
switch ( strtolower( $type ) ) {
case 'weekday':
$included_day_type_indexes = array_merge( $included_day_type_indexes, range( 1, 5 ) );
break;
case 'weekend':
$included_day_type_indexes = array_merge( $included_day_type_indexes, range( 6, 7 ) );
break;
case 'monday':
case 'mon':
$included_day_type_indexes[] = 1;
break;
case 'tuesday':
case 'tues':
case 'tue':
case 'tu':
$included_day_type_indexes[] = 2;
break;
case 'wednesday':
case 'wed':
$included_day_type_indexes[] = 3;
break;
case 'thursday':
case 'thurs':
case 'thur':
case 'thu':
case 'th':
$included_day_type_indexes[] = 4;
break;
case 'friday':
case 'fri':
$included_day_type_indexes[] = 5;
break;
case 'saturday':
case 'caturday':
case 'sat':
$included_day_type_indexes[] = 6;
break;
case 'sunday':
case 'sun':
$included_day_type_indexes[] = 7;
break;
}
}
$included_day_type_indexes = array_unique( $included_day_type_indexes );
}
$date = strtotime( $start_date );
$end = strtotime( $end_date );
while ( $date <= $end ) {
if ( in_array( date( 'N', $date ), $included_day_type_indexes ) ) {
$count++;
}
$date = strtotime( '+1 day', $date );
}
return $count;
}
/*** EXAMPLES ***/
echo get_days_between_dates( '2017-08-21', '2017-09-03' ) . "\n";
echo get_days_between_dates( '2017-08-21', '2017-09-03', array( 'weekday', 'weekend' ) ) . "\n";
echo get_days_between_dates( '2017-08-21', '2017-09-03', array( 'mon' ) ) . "\n";
echo get_days_between_dates( '2017-08-21', '2017-09-03', array( 'weekday' ) ) . "\n";
echo get_days_between_dates( '2017-08-21', '2017-09-03', array( 'mon', 'wednesday', 'fri' ) ) . "\n";
This is the output of the examples…
14
14
2
10
6
What do you think? What would you do different?
I put the function up on GitHub. Submit a pull request if you have improvements.
Like this:
Like Loading...