Reputation: 7906
I want to calculate the number of weekdays days in a give month and year. Weekdays means monday to friday. How do i do it ?
Upvotes: 9
Views: 10897
Reputation: 351
I created a simple function that takes the $first_day_of_month (week day like Sunday/Monday etc). You can find out the first day of month like this:
date('N', strtotime(date("01-m-Y")));
And using the $month_last_date which can be procured like this:
date("t");
Here is the function:
function workingDaysInMonth(int $first_day_of_month, int $month_last_date) : array
{
$working_days = [];
$day = $first_day_of_month;
$working_day_count = 0;
for ($i = 1; $i <= $month_last_date; $i++) {
if ($day == 8) {
$day = 1;
}
if (!($day == 6 || $day == 7)) {
$working_day_count++;
$working_days[$i] = $working_day_count;
}
$day++;
}
return $working_days;
}
Upvotes: 0
Reputation: 101
function workingDays($m,$y) {
$days = cal_days_in_month(CAL_GREGORIAN, $m, $y);
$workig_days = 0;
$days_rest = array(5,6); //friday,saturday
for ( $d=1 ; $d < $days+1 ; $d++ ) {
if ( !in_array(date("w",strtotime("{$d}-{$m}-{$y}")),$days_rest) ) {
$workig_days++;
}
}
return $workig_days;
}
Upvotes: 0
Reputation: 147
try this one
function getWeekdays($m, $y = NULL){
$arrDtext = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri');
if(is_null($y) || (!is_null($y) && $y == ''))
$y = date('Y');
$d = 1;
$timestamp = mktime(0,0,0,$m,$d,$y);
$lastDate = date('t', $timestamp);
$workingDays = 0;
for($i=$d; $i<=$lastDate; $i++){
if(in_array(date('D', mktime(0,0,0,$m,$i,$y)), $arrDtext)){
$workingDays++;
}
}
return $workingDays;
}
Upvotes: 2
Reputation: 852
These functions work Without Loops.
The functions calculate the number of weekdays using:
// main functions
// weekdays in month of year
function calculateNumberOfWeekDaysAtDate($month, $year)
{
// I'm sorry, I don't know the right format for the $month and $year, I hope this is right.
// PLEASE CORRECT IF WRONG
$firstMondayInCurrentMonth = (int) date("j", strtotime("first monday of 01-$month-$year")); //get first monday in month for calculations
$numberOfDaysOfCurrentMonth = (int) date("t", strtotime("01-$month-$year")); // number of days in month
return calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth);
}
// week days in current month
function calculateNumberOfWeekDaysInCurrentMonth()
{
$firstMondayInCurrentMonth = (int) date("j", strtotime("first monday of this month")); //get first monday in month for calculations
$numberOfDaysOfCurrentMonth = (int) date("t"); // number of days in this month
return calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth);
}
// helper functions
function calculateNumberOfWeekDaysFromFirstMondayAndNumberOfMonthDays($firstMondayInCurrentMonth, $numberOfDaysOfCurrentMonth)
{
return $numberOfWeekDays = (($start = ($firstMondayInCurrentMonth - 3)) < 0 ? 0 : $start) + floor(($numberOfDaysOfCurrentMonth - ($firstMondayInCurrentMonth - 1)) / 7) * 5 + (($rest = (($numberOfDaysOfCurrentMonth - ($firstMondayInCurrentMonth - 1)) % 7)) <= 5 ? $rest : 5);
}
Upvotes: 0
Reputation: 1356
I've come up with a non-loop function. Much better in terms of performance. It might seem messy but it just needs to ask PHP the first day's weekday and the month's number days: the rest are arithmetical operations based on logic.
function countWorkDays($year, $month)
{
$workingWeekdays = 5;
$firstDayTimestamp = mktime(0, 0, 0, $month, 1, $year);
$firstDayWeekDay = (int)date("N", $firstDayTimestamp); //1: monday, 7: saturday
$upToDay = (int)date("t", $firstDayTimestamp);
$firstMonday = 1 === $firstDayWeekDay ? 1 : 9 - $firstDayWeekDay;
$wholeWeeks = $firstMonday < $upToDay ? (int)floor(($upToDay - $firstMonday + 1) / 7) : 0;
$extraDays = ($upToDay - $firstMonday + 1) % 7;
$initialWorkdays = $firstMonday > 1 && $firstDayWeekDay <= $workingWeekdays ? $workingWeekdays - $firstDayWeekDay + 1 : 0;
$workdaysInWholeWeeks = $wholeWeeks * $workingWeekdays;
$extraWorkdays = $extraDays <= $workingWeekdays ? $extraDays : $workingWeekdays;
return $initialWorkdays + $workdaysInWholeWeeks + $extraWorkdays;
}
Upvotes: 0
Reputation: 27
Calculate working days in a month from any date:
public function getworkd($mday)
{
$dn = new DateTime($mday);
$dfrom = $dn->format('Y-m-01');
$dtill = $dn->format('Y-m-t');
$df = new DateTime($dfrom);
$dt = new DateTime($dtill);
$wdays = 0;
while($df<=$dt)
{
$dof= $df->format('D') ;
if( $dof == 'Sun' || $dof == 'Sat' ) ; else $wdays++;
$df->add(new DateInterval('P1D'));
}
return $wdays;
}
Upvotes: 1
Reputation: 176
DateObject method:
function getWorkingDays(DateTime $date) {
$month = clone $date;
$month->modify('last day of this month');
$workingDays = 0;
for ($i = $month->format('t'); $i > 28; --$i) {
if ($month->format('N') < 6) {
++$workingDays;
}
$month->modify('-1 day');
}
return 20 + $workingDays;
}
Upvotes: 1
Reputation: 43552
Get the number of working days without holidays between two dates :
echo number_of_working_days('2013-12-23', '2013-12-29');
3
Upvotes: 1
Reputation: 886
this will work
// oct. 2013
$month = 10;
// loop through month days
for ($i = 1; $i <= 31; $i++) {
// given month timestamp
$timestamp = mktime(0, 0, 0, $month, $i, 2012);
// to be sure we have not gone to the next month
if (date("n", $timestamp) == $month) {
// current day in the loop
$day = date("N", $timestamp);
// if this is between 1 to 5, weekdays, 1 = Monday, 5 = Friday
if ($day == 1 OR $day <= 5) {
// write it down now
$days[$day][] = date("j", $timestamp);
}
}
}
// to see if it works :)
print_r($days);
Upvotes: -1
Reputation: 301
You don't need to count every day in the month. You already know the first 28 days contain 20 weekdays no matter what. All you have to do is determine the last few days. Change the start value to 29. Then add 20 weekdays to your return value.
function get_weekdays($m,$y) {
$lastday = date("t",mktime(0,0,0,$m,1,$y));
$weekdays=0;
for($d=29;$d<=$lastday;$d++) {
$wd = date("w",mktime(0,0,0,$m,$d,$y));
if($wd > 0 && $wd < 6) $weekdays++;
}
return $weekdays+20;
}
Upvotes: 30
Reputation: 95
This is the simplest code I could come up with. You really would need to create an array or a database table to hold the holidays to get a true, "Working Days" count, but that wasn't what was asked, so here you go, hope this helps someone.
function get_weekdays($m,$y) {
$lastday = date("t",mktime(0,0,0,$m,1,$y));
$weekdays=0;
for($d=1;$d<=$lastday;$d++) {
$wd = date("w",mktime(0,0,0,$m,$d,$y));
if($wd > 0 && $wd < 6) $weekdays++;
}
return $weekdays;
}
Upvotes: 1
Reputation: 47321
Find the last day and the weekday for the given month
then do a simple while loop like :-
$dates = explode(',', date('t,N', strtotime('2013-11-01')));
$day = $dates[1];
$tot = $dates[0];
$cnt = 0;
while ($tot>1)
{
if ($day < 6)
{
$cnt++;
}
if ($day == 1)
{
$day = 7;
}
else
{
$day--;
}
$tot--;
}
$cnt = total of weekday (Monday to Friday) for a given month
Upvotes: 0
Reputation:
Some basic code:
$month = 12;
$weekdays = array();
$d = 1;
do {
$mk = mktime(0, 0, 0, $month, $d, date("Y"));
@$weekdays[date("w", $mk)]++;
$d++;
} while (date("m", $mk) == $month);
print_r($weekdays);
Remove the @
if your PHP error warning doesn't show notices.
Upvotes: 2