Skip to content

Instantly share code, notes, and snippets.

@massiws
Last active August 17, 2022 05:15
Show Gist options
  • Save massiws/9593008 to your computer and use it in GitHub Desktop.
Save massiws/9593008 to your computer and use it in GitHub Desktop.
PHP Count the number of working days between two dates.
<?php
/**
* Count the number of working days between two dates.
*
* This function calculate the number of working days between two given dates,
* taking account of the Public festivities, Easter and Easter Morning days,
* the day of the Patron Saint (if any) and the working Saturday.
*
* @param string $date1 Start date ('YYYY-MM-DD' format)
* @param string $date2 Ending date ('YYYY-MM-DD' format)
* @param boolean $workSat TRUE if Saturday is a working day
* @param string $patron Day of the Patron Saint ('MM-DD' format)
* @return integer Number of working days ('zero' on error)
*
* @author Massimo Simonini <[email protected]>
*/
function getWorkdays($date1, $date2, $workSat = FALSE, $patron = NULL) {
if (!defined('SATURDAY')) define('SATURDAY', 6);
if (!defined('SUNDAY')) define('SUNDAY', 0);
// Array of all public festivities
$publicHolidays = array('01-01', '01-06', '04-25', '05-01', '06-02', '08-15', '11-01', '12-08', '12-25', '12-26');
// The Patron day (if any) is added to public festivities
if ($patron) {
$publicHolidays[] = $patron;
}
/*
* Array of all Easter Mondays in the given interval
*/
$yearStart = date('Y', strtotime($date1));
$yearEnd = date('Y', strtotime($date2));
for ($i = $yearStart; $i <= $yearEnd; $i++) {
$easter = date('Y-m-d', easter_date($i));
list($y, $m, $g) = explode("-", $easter);
$monday = mktime(0,0,0, date($m), date($g)+1, date($y));
$easterMondays[] = $monday;
}
$start = strtotime($date1);
$end = strtotime($date2);
$workdays = 0;
for ($i = $start; $i <= $end; $i = strtotime("+1 day", $i)) {
$day = date("w", $i); // 0=sun, 1=mon, ..., 6=sat
$mmgg = date('m-d', $i);
if ($day != SUNDAY &&
!in_array($mmgg, $publicHolidays) &&
!in_array($i, $easterMondays) &&
!($day == SATURDAY && $workSat == FALSE)) {
$workdays++;
}
}
return intval($workdays);
}
@lengocthuan
Copy link

perfect, thanks very much!

@sayedsaddam
Copy link

sayedsaddam commented May 28, 2019

How do we use it with PHP Codeigniter ?

@mzvarik
Copy link

mzvarik commented Nov 28, 2020

Using "define" in a function is really bad.

@massiws
Copy link
Author

massiws commented Nov 29, 2020

@mzvarik, you are right, but this function was extracted from a Drupal 7 module I develop some years ago.
Sure, today it can be written in a better way.

@letsjump
Copy link

letsjump commented Feb 12, 2021

Great work! This inspired me to create a PHP object that implements some of your ideas.
WorkingDayHelper class

=== UPDATE ===

The Gist is abandoned in favor of a complete Github repo that contains the library, a better README, and the Composer installer.
Give a try to letsjump/workday-helper-php

It counts the workdays and also returns a calendar of closing events for the specified range of dates.

@massiws
Copy link
Author

massiws commented Jul 9, 2022

@letsjump, great job!

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