Sander
Sander

Reputation: 1401

Finding all weekdays in a month

How do I go about getting all the work days (mon-fri) in a given time period (let's say, today till the end of the next month) ?

Upvotes: 1

Views: 2991

Answers (7)

Francois Deschenes
Francois Deschenes

Reputation: 24989

// Find today's day of the month (i.e. 15)
$today = intval(date('d'));

// Define the array that will hold the work days.
$work_days = array()

// Find this month's last day. (i.e. 30)
$last = intval(date('d', strtotime('last day of this month')));

// Loop through all of the days between today and the last day of the month (i.e. 15 through 30)
for ( $i = $today; $i <= $last; $i++ )
{
  // Create a timestamp.
  $timestamp = mktime(null, null, null, null, $i);

  // If the day of the week is greater than Sunday (0) but less than Saturday (6), add the timestamp to an array.
  if ( intval(date('w', $timestamp)) > 0 && intval(date('w', $timestamp)) < 6 )
    $work_days[] = mktime($timestamp);
}

The $work_days array will contain timestamps which you could use this way:

echo date('Y-m-d', $work_days[0]);

The code above with work in PHP 4 as well as PHP 5. It does not rely on the functionality of the DateTime class which was not available until PHP 5.2 and does not require the use of "libraries" created by other people.

Upvotes: 1

tplaner
tplaner

Reputation: 8471

If you're using PHP 5.2+ you can use the library I wrote in order to handle date recursion in PHP called When.

With the library, the code would be something like:

$r = new When();
$r->recur(<start date here>, 'weekly')
  ->until(<end date here>)
  ->wkst('SU')
  ->byday(array('MO', 'TU', 'WE', 'TH', 'FR'));

while($result = $r->next())
{
    echo $result->format('c') . '<br />';
}

Upvotes: 3

Wesley van Opdorp
Wesley van Opdorp

Reputation: 14951

This sample does exactly what you need, in an quick and efficient way. It doesn't do nested loops and uses the totally awesome DateTime object.

$oDateTime = new DateTime();
$oDayIncrease = new DateInterval("P1D");

$aWeekDays = array();
$sStart = $oDateTime->format("m-Y");
while($oDateTime->format("m-Y") == $sStart) {
    $iDayInWeek = $oDateTime->format("w");
    if ($iDayInWeek > 0 && $iDayInWeek < 6) {
        $aWeekDays[] = clone $oDateTime;

    }
    $oDateTime->add($oDayIncrease);
}

Upvotes: 3

Chris Baker
Chris Baker

Reputation: 50622

Try it here: http://codepad.org/wuAyAqnF

To use it, simply pass a timestamp to get_weekdays. You'll get back an array of all the weekdays, as timestamps, for the rest of the current month. Optionally, you can pass a $to argument - you will get all weekdays between $from and $to.

function get_weekdays ($from, $to=false) {
    if ($to == false)
        $to = last_day_of_month($from);

    $days = array();

    for ($x = $from; $x < $to; $x+=86400 ) {
        if (date('w', $x) > 0 && date('w', $x) < 6)
            $days[] = $x;
    }
    return $days;       
}

function last_day_of_month($ts=false) {
    $m = date('m', $ts);
    $y = date('y', $ts);
    return mktime(23, 59, 59, ($m+1), 0, $y);
}

Upvotes: 2

initall
initall

Reputation: 2385

This code does at least one part you ask for. Instead of "end of next month" it simply works with a given number of days.

$dfrom = time();
$fourweeks = 7 * 4;

for ($i = 0; $i < $fourweeks; $i ++) {
    $stamp = $dfrom + ($i * 24 * 60 * 60);
    $weekday = date("D", $stamp);
    if (in_array($weekday, array("Mon", "Tue", "Wed", "Thu", "Fri"))) {
        print date(DATE_RSS, $stamp) . "\n";
    }
}

Upvotes: 1

jefflunt
jefflunt

Reputation: 33954

Pseudocode coming your way:

Calculate the number of days between now and the last day of the month Get the current day of the week (i.e. Wednesday) Based on the current day of the week, and the number of days left in the month, it's simple calculation to figure out how many weekend days are left in the month - it's going to be the number of days remaining in the month, minus the number of Sundays/Saturdays left in the month.

I would write a function, something like:

daysLeftInMonth(daysLeftInMonth, startingDayOfWeek, dayOfWeekToCalculate)

where:

  • daysLeftInMonth is last day of the month (30), minus the current date (15)
  • startingDayOfWeek is the day of the week you want to start on (for today it would be Wednesday)
  • dayOfWeekToCalculate is the day of the week you want to count, e.g. Saturday or Sunday. June 2011 currently has 2 Sunday, and 2 Saturdays left 'til the end of the month

So, your algorithm becomes something like:

getWeekdaysLeft(todaysDate)

...getWeekdaysLeft is something like:

sundaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Sunday");
saturdaysLeft = daysLeftInMonth(lastDayOfMonth - todaysDate, "Wednesday", "Saturday");
return ((lastDayOfMonth - todaysDate) - (sundaysLeft + saturdaysLeft));

Upvotes: 1

m.edmondson
m.edmondson

Reputation: 30922

I suppose you could loop through the dates and check the day for each one, and increment a counter.

Can't think of anything else off the top of my head.

Upvotes: 1

Related Questions