1

Assume today is Feb 21, 2011 ( Monday ). It is the third Monday of this month. If date is given as input, How can I know how many Mondays have passed before it?

In PHP, how to know how many mondays have passed in this month uptil today?

Salman Virk
  • 12,007
  • 9
  • 36
  • 47

6 Answers6

4

That sounds like a pretty straightforward division calculation. From the current date, subtract number of days past last monday (example: wednesday = -2), divide it by 7 and ceil() it to round it up.

EDIT: That will include the current monday in the number, returning "3" for monday 21st.

Kaivosukeltaja
  • 15,541
  • 4
  • 40
  • 70
  • Works for Feb 21, but not for Feb 1. If he had used 2/1/2011 as his example, you'd be returning "1" for Tuesday 2/1, (or if he's not careful he could be returning the number of Monday's in January). – Farray Feb 21 '11 at 20:30
  • My mistake, poor choice of words. By "date" I mean "day of the month". So subtracting one (because it's tuesday) from one results in zero, which rounds up to zero. – Kaivosukeltaja Feb 22 '11 at 06:13
  • Right, the core formula is `ceil( day_of_month / 7 )`. But you need to subtract the days (-2 for wed in your example) since he asked for mondays. – Justin Ethier Aug 03 '11 at 20:14
  • @Justin: Yes, I believe that's mentioned in my answer. :) – Kaivosukeltaja Aug 04 '11 at 12:14
  • @Kaivosukeltaja: Agreed :) - Sorry for the poor wording in the second half of my comment. I was just trying to make it easier for me to understand what was going on here... perhaps it will help the next guy, perhaps not... – Justin Ethier Aug 04 '11 at 13:17
4
$now=time() + 86400;
if (($dow = date('w', $now)) == 0) $dow = 7; 
$begin = $now - (86400 * ($dow-1));

echo "Mondays: ".ceil(date('d', $begin) / 7)."<br/>";

works for me....

EDIT: includes today's monday too

david.wosnitza
  • 763
  • 4
  • 10
0

You could loop through all the days until now and count the mondays:

$firstDate = mktime(0, 0, 0, date("n"), 1, date("Y"));
$now = time();
$mondays = 0;
for ($i = $firstDate; $i < $now; $i = $i + 24*3600) {
    if (date("D", $i) == "Mon")
        $mondays ++;
}

Haven't tested this script

Robin
  • 8,197
  • 11
  • 45
  • 74
  • Using this approach, we may loop by getting "last monday" until `last monday`'s date belongs to previous month – Salman Virk Feb 21 '11 at 19:06
  • Fixed the script, the j was supposed to be an n. It works now, but I would still prefer Kaivosukeltaja's solution, much simpler to do it with some basic math. – Robin Feb 21 '11 at 20:17
0
    <?php

 function mondays_get($month, $stop_if_today = true) {

$timestamp_now = time();

for($a = 1; $a < 32; $a++) {

    $day = strlen($a) == 1 ? "0".$a : $a;
    $timestamp = strtotime($month . "-$day");
    $day_code = date("w", $timestamp);
    if($timestamp > $timestamp_now)
        break;
    if($day_code == 1)
        @$mondays++;

}

return $mondays;
}

echo mondays_get('2011-02');

Hope this is of use to you! i've just rolled it up.

"Beware of bugs in the above code; I have only proved it correct, not tried it."

Works OK afaik

Pedro
  • 1,001
  • 11
  • 16
0

Try this...

//find the most recent monday (doesn't find today if today is Monday though)
$startDate = strtotime( 'last monday' );

//if 'last monday' was not this month, 0 mondays.  
//if 'last monday' was this month, count the weeks
$mondays = date( 'm', $startDate ) != date( 'm' ) 
         ? 0 
         : floor( date( 'd', $startDate ) / 7 );

//increment the count if today is a monday (since strtotime didn't find it)
if ( date( 'w' ) == 1 ) $mondays++;
Farray
  • 8,290
  • 3
  • 33
  • 37
0

Another way is to find what day of the week is today, find the first such day of the month via some magic strtotime(), then calculate the difference between that and now in weeks. See below for a function that will take a Y-m-d formatted date() and return which weekday of the month it is.

Note: strtotime needs to be verbose, including "of" and the month: "first Monday of 2011-02" otherwise it advances one day. This bit me when I was testing edge cases.

Also added some display pepper which is completely optional but I felt like it.

function nthWeekdayOfMonth($day) {

    $dayTS = strtotime($day) ;

    $dayOfWeekToday = date('l', $dayTS) ;

    $firstOfMonth = date('Y-m', $dayTS) . "-01" ;
    $firstOfMonthTS = strtotime($firstOfMonth) ;

    $firstWhat = date('Y-m-d', strtotime("first $dayOfWeekToday of $monthYear", $firstOfMonthTS)) ;
    $firstWhatTS = strtotime($firstWhat) ;

    $diffTS = $dayTS - $firstWhatTS ;
    $diffWeeks = $diffTS / (86400 * 7);

    $nthWeekdayOfMonth = $diffWeeks + 1;

    return $nthWeekdayOfMonth ;
}

$day = date('Y-m-d') ;
$nthWeekdayOfMonth = nthWeekdayOfMonth($day) ;

switch ($nthWeekdayOfMonth) {
    case 1: 
        $inflector = "st" ;
        break ;
    case 2: 
        $inflector = "nd" ;
        break ;
    case 3: 
        $inflector = "rd" ;
        break ;
    default:
        $inflector = "th" ;
}

$dayTS = strtotime($day) ;

$monthName = date('F', $dayTS) ;    
$dayOfWeekToday = date('l', $dayTS) ;

echo "Today is the {$nthWeekdayOfMonth}$inflector $dayOfWeekToday in $monthName" ;
Community
  • 1
  • 1
Fanis Hatzidakis
  • 5,282
  • 1
  • 33
  • 36