tags:

views:

158

answers:

6

If we have date range such As:

1st October 2009 - 20th October 2009

Can we calculate how many Mondays have occured during

The answer to this would be (3)

  M   T   W   T   F   S   S
             *1   2   3   4
  5   6   7   8   9  10  11
 12  13  14  15  16  17  18
 19 *20  21  22  23  24  25
 26  27  28  29  30  31

Can we do this in MySQL, if not can it be done in PHP or would i have to create a function

A: 
function daysBetween($from, $to, $round = true) {
    // assume from and two can be valid date() values or strings
    $from = strtotime($from);
    $to = strtotime($to);
    $diff = $to - $from;
    $days = $diff / 86400;
    return ($round) ? floor($days) : round($days, 2);
}
cballou
that would only give the number of days between 2 dates.. wont it?
Sabeen Malik
Any chance you can change the return to reflect If conditions....:D Please
Shahmir Javaid
O wait NVM... the above will only return the Number of days between two dates
Shahmir Javaid
+1  A: 

You can start with something like:

select datecol1, TIMESTAMPDIFF(DAY,datecol1,datecol2) as numDays from table;

Then in PHP, you can pretty directly figure out how many mondays follow d1, depending on what day of the week d1 is (you can use date() and strtotime() to figure this out), and the value of numDays in the result set.

EDIT: Untested code, but the general idea should work:

function daysUntilMonday($date){
    $dayOfWeek = date('w',strtotime($date));  //a number from 0-6, sunday is 0
    $daysTillMonday = (8 - $dayOfWeek) % 7; //modulus is your friend.
    return $daysTillMonday;    
}

function countMondays($start,$numDays){
    $numDays = $numDays - daysUntilMonday($start);
    return floor($numDays/7)+1;
}

Could be off by one, but should be generally the right approach.

HTH

timdev
OO that gives me the days that occured between. Now i need to find out howmany mondays occured :(
Shahmir Javaid
+1  A: 

not sure if its possible with MySQL . PHP is ur friend there.. several ways to go about it .. get start timestamp and end timestamp by using strtotime probably .. then run a for loop or something from start timestamp to end timestamp by adding 86400 and on each increment check the date("D" , $mkt) == 'Mon' and see if its Monday and then increment ur counter. have given u the rough idea.. u can figure out the code from there.

Sabeen Malik
I think using timedev solution with a combination of cballou solution i can do it in MYSQL Function.
Shahmir Javaid
well if u want to write a procedure for that then i am sure its very much possible with MySQL .. otherwise i cant think of a reasonable way to go about it other than creating a temp table or something. Getting the days is not a problem at all .. but making sure u have the right number of mondays is the core issue. If you do get to do it with MySQL .. please do share with us here.
Sabeen Malik
It would indeed be neat to see a function in mySQL. You could probably use my (probably flakey) php code as a jumping off point. The tricky parts of this kind of date counting are always the edge cases (what happens when there are zero mondays between the dates, etc)
timdev
@Sab: Will do... but it will take time@timedev: zero mondays should return 0
Shahmir Javaid
+1  A: 

sdt = start date of interval, edt = end date of interval. Change '2' to reflect the day of the week you want to count.

CREATE FUNCTION NMONDAYS( sdt DATETIME,  edt DATETIME ) 
RETURNS INT DETERMINISTIC RETURN TIMESTAMPDIFF( WEEK, sdt, edt ) 
+ IF( DAYOFWEEK( edt ) >= 2 AND DAYOFWEEK( edt ) < DAYOFWEEK( sdt ),1,0)
martin clayton
Will Try that... and let you know
Shahmir Javaid
You sexy S0B... Love ya.... btw is 1: Sunday 2: Monday 3: Tuesday... and so On?
Shahmir Javaid
Yes they are: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_dayofweek
martin clayton
Oooo problemo...kind off. You have to be carefull if the dates are entered wrong and if the dates are exactly the same for example 2009 Oct 05 has 1 monday but the return value is 0
Shahmir Javaid
No one would ever do that? Would they? I guess you could add another IF to handle that, something like 'IF ( DATEDIFF( edt, sdt ) = 0 AND DAYOFWEEK( edt ) = 2,1,0)'.
martin clayton
Yep :D..... Thanks none the less. :D
Shahmir Javaid
A: 

In sql:

SELECT DATEDIFF(
        ADDDATE('20091001', 9 - CASE WHEN DAYOFWEEK('20091001') = 1 THEN 8
                                     WHEN DAYOFWEEK('20091001') = 2 THEN 9
                                     ELSE DAYOFWEEK('20091001') 
                                END), -- first monday after date1
        ADDDATE('20091020', 2 - CASE WHEN DAYOFWEEK('20091020') = 1 THEN 8
                                     ELSE DAYOFWEEK('20091020') 
                                END)  -- first monday before date2
               )/7 + 1 -- divide the difference by 7 gives number of weeks
                       -- add 1 (nb points = nb intervals + 1)
              ) NbMonday
najmeddine
A: 

Or this:

// Pass $date_1, $date_2 as timestamps, $dow as 3-letter abbrev. (e.g. 'Mon').
// Dates can be low to high or high to low.

function dow_between($date_1, $date_2, $dow)
{
    if ($date_2 < $date_1) {
        list($date_2, $date_1) = array($date_1, $date_2);
    }
    for ($num_dow = -1; $date_1 <= $date_2; $num_dow++) {
        $date_1 = strtotime('next ' . $dow, $date_1);
    }
    return $num_dow;
}

Edited to handle dates in either order.

GZipp