FilChi Weblog

Getting the first monday of the month

Posted by: phpcurious on: February 27, 2008

I thought I should share with my fellows this function I just created to get the first monday of the month using PHP.

function get_firstmonday($month,$year) {

$num = date(”w”,mktime(0,0,0,$month,1,$year));
if($num>1)
return date(”Y-M-d H:i:s”,mktime(0,0,0,$month,1,$year)+(86400*(8-$num)));
else
return date(”Y-M-d H:i:s”,mktime(0,0,0,$month,1,$year));
}

To use this function, simply provide your month as a number ranging from 1~12 and $year ranging from 1970 ~ future:

echo get_firstmonday(5,2008);

Update: please go to the comments for the correction of this function.
Thanks to Ben Donoghue for the correction!

15 Responses to "Getting the first monday of the month"

Hey,

Just had a nosey at your function and cool, it works great…

…except when you try something like [code]echo get_firstmonday(6,2008);[/code]

This gives 2008-06-09 00:00:00 which is the second Monday. This is because date(’w') gives the days of the week STARTING ON SUNDAY as 0. Therefore, any month starting on a Sunday will not work correctly. For myself I’ve made a small change if you’re interested:

[code]
function get_firstmonday($month,$year){

$num = date("w",mktime(0,0,0,$month,1,$year));
if($num==1)
return date("Y-M-d H:i:s",mktime(0,0,0,$month,1,$year));
elseif($num>1)
return date("Y-M-d H:i:s",mktime(0,0,0,$month,1,$year)+(86400*(8-$num)));
else
return date("Y-M-d H:i:s",mktime(0,0,0,$month,1,$year)+(86400*(1-$num)));

}
[/code]

I’ve not tried it but you may be able to use date(’N') in your original function to get Sunday as 7 instead of 0.

Cheers for it!

@Ben,

First of all, thank you very much for visiting my site.

Yes, you are right about my function. I overlooked it in that way.

And thanks for the correction.

How about getting the second, third and fourth Mondays?
Can you please help me?

@karlamarie,
thanks for visiting my site.

after getting the first monday of the month, maybe, you can just add up
7 days to the first monday to get second monday of the month. and, another 7 days to the second monday to get the third monday of the month, and so on.

for example, after calling the function, change it back to unix timestamp. And then, add (7*60*60*24) to it, and then calculate it with PHP date function.

Hi

i have a posted date and day number (sunday=0, monday=1 etc),
i want a function that calculate next immediate date depending on the day number passed to the function.

I have a function which calculate the first, last,second ,forth day of current month… but i this function wont work if i give the posted date .

$answer=strftime(”%d-%m-%Y”, get_first_day($daym, $cur_month, $cur_year,$onthe));

function get_first_day($day_number, $month, $year, $onthe)
{
$month = ($month === false) ? strftime(”%m”): $month;
$year = ($year === false) ? strftime(”%Y”): $year;

$first_day = 1 + ((7+$day_number – strftime(”%w”, mktime(0,0,0,$month, 1, $year)))%7);
if($onthe ==’1′)
{
$set_value =”";
}
elseif($onthe ==’2′)
{
$set_value =”7″;
}
elseif($onthe ==’3′)
{
$set_value =”14″;
}
elseif($onthe ==’4′)
{
$set_value =”21″;
}
elseif($onthe ==’5′)
{
//if current day of week is sunday, than only we manupulate this otherwise it will take $set_value =”21″;
$set_value =”21″;
}
return mktime(0,0,0,$month, $first_day+$set_value, $year);
}

This will give you any occurrence of a day of week. For example, the third Tuesday of the month, the last Friday of the month, the second Monday of the month… you get the picture.

$DOW = day of the week (0 = Sunday, 6 = Saturday).
$X = occurence (1 = first, 2 = third, etc..). If the given month does not have the occurrence, then it will return the last. For example, if you ask for the 7th occurrence of Friday, it will return the last Friday of the month.
$M = month
$Y = year

Example, get_Xth_DOW(2,3,7,2009) will return the third Tuesday of July 2009. It just returns the day. If you want the date you can just do
$D = get_Xth_DOW($DOW,$X,$M,$Y);
echo $M . “/” . $D . “/” . $Y;

function get_Xth_DOW($DOW,$X,$M,$Y) {
$numDays = date(’t',mktime(0,0,0,$M,1,$Y));
$add = 7*($X – 1);
$firstDOW = date(’w',mktime(0,0,0,$M,1,$Y));
$diff = $firstDOW – $DOW;
$d = 1;
if($diff > 0) { $d += (7 – $diff); }
else if ($diff $numDays) { $d -= 7; }
return $d;
}

I just realized that I didn’t post the entire code. Sorry, here is the entire function.

function get_Xth_DOW($DOW,$X,$M,$Y) {
$numDays = date(’t',mktime(0,0,0,$M,1,$Y));
$add = 7*($X – 1);
$firstDOW = date(’w',mktime(0,0,0,$M,1,$Y));
$diff = $firstDOW – $DOW;
$d = 1;
if($diff > 0) { $d += (7 – $diff); }
else if ($diff $numDays) { $d -= 7; }
return $d;
}

@JoeDundas, the next to last line of your function (else if) is missing a comparison operator between $diff and $numDays, no?

@joe dundas

Your code was a bit flawed, with some calculations totally overlooked. For one, the missing comparison operator that kook pointed out. Two, you declared and assigned $add but never used it anywhere. It should have been used in the comparisons at the end of the function where the numeral 7 was written. Three, if the elseif statement was true, the re-assigned variable of $d (in your case) would not have been assigned a meaningful result without further manipulation.

Nevertheless, I read the intended meaning of your code, and took it upon myself to correct it for all those unsure of the required modifications, as your function is still pretty handy.

The code below is the corrected version of joe’s function, for anyone that needs this functionality but couldn’t get the desired results.

function get_xth_dow($dow, $occurence, $m, $y)
{
$numdays = date(’t', mktime(0, 0, 0, $m, 1, $y));
$add = 7 * ($occurence – 1);
$firstdow = date(’w',mktime(0, 0, 0, $m, 1, $y));
$diff = $firstdow – $dow;

$day_of_month = 1;
if($diff > 0)
{
$day_of_month += ($add – $diff);
}
elseif ($diff < $numdays)
{
$day_of_month -= ($diff – $add);
}
return $day_of_month;
}

Alright–completely disregard the last piece of code I posted. It doesn’t work–it only worked for the month of March 2009. Outside of that month, it simply did not work. After several hours of coding, trying to make it possible to get the date within a month from the name of day in that month, and moreover its nth occurrence, I have written the following from scratch. I guarantee it works, as it was tested with dozens of month, name day, and year combinations.

The function works with timestamps. You can replace date(’d', $date_of_occurrence) with $date_of_occurrence to simply return the timestamp of the result date, otherwise it will return a two-digit representation of the date with a leading 0 if date is only one digit.

$occurrence represents the first, second, third, fourth, or fifth occurrence of $name_of_day in the given month

$name_of_day represented by numerals 1 to 7 (Monday to Sunday, respectively)
—————————————————————————–

function date_from_nameday($occurrence, $name_of_day, $month, $year)
{
$one_day = 24 * 60 *60;
$one_week = 7 * $one_day;

$one = mktime(0, 0, 0, $month, 1, $year);
$two = $one + $one_day;
$three = $two + $one_day;
$four = $three + $one_day;
$five = $four + $one_day;
$six = $five + $one_day;
$seven = $six + $one_day;

$first = date(’N', $one);
$second = date(’N', $two);
$third = date(’N', $three);
$fourth = date(’N', $four);
$fifth = date(’N', $five);
$sixth = date(’N', $six);
$seventh = date(’N', $seven);

switch($name_of_day)
{
case $first: $first_occurrence = $one; break;
case $second: $first_occurrence = $two; break;
case $third: $first_occurrence = $three; break;
case $fourth: $first_occurrence = $four; break;
case $fifth: $first_occurrence = $five; break;
case $sixth: $first_occurrence = $six; break;
case $seventh: $first_occurrence = $seven; break;
}

$date_of_occurrence = ($occurrence > 1) ? $first_occurrence + ($one_week * ($occurrence – 1)) : $first_occurrence;

return date(’d', $date_of_occurrence); // manipulate timestamp
}

—————————————————————————-
Example usage

Get the second Sunday in March for DST:

$second_sunday_of_march = date_from_nameday(2, 7, 3, 2009);

My site contains my email if you have any questions.

Although your code is correct but it doesn’t return last day if we need to get that. For instance try this

echo date_from_nameday(5,1,4,2009);

you will get day of next month, I have corrected your code and here is the correct function .. Tested and working!

function date_from_nameday($occurrence, $name_of_day, $month, $year)
{
$one_day = 24 * 60 *60;
$one_week = 7 * $one_day;

$one = mktime(0, 0, 0, $month, 1, $year);
$two = $one + $one_day;
$three = $two + $one_day;
$four = $three + $one_day;
$five = $four + $one_day;
$six = $five + $one_day;
$seven = $six + $one_day;

$first = date(’N', $one);
$second = date(’N', $two);
$third = date(’N', $three);
$fourth = date(’N', $four);
$fifth = date(’N', $five);
$sixth = date(’N', $six);
$seventh = date(’N', $seven);

switch($name_of_day)
{
case $first: $first_occurrence = $one; break;
case $second: $first_occurrence = $two; break;
case $third: $first_occurrence = $three; break;
case $fourth: $first_occurrence = $four; break;
case $fifth: $first_occurrence = $five; break;
case $sixth: $first_occurrence = $six; break;
case $seventh: $first_occurrence = $seven; break;
}

$date_of_occurrence = ($occurrence > 1) ? $first_occurrence + ($one_week * ($occurrence – 1)) : $first_occurrence;

$day_to_return = date(’d', $date_of_occurrence);
$month_of_day = date(’m', $date_of_occurrence);
if ($month_of_day != $month)
return -1;
else
return $day_to_return;
}

Getting the first monday of the month in Ruby

def self.find_by_year_month(year, month)
d = Date.parse(”01-#{month}-#{year}”)

# Get the beginning of the month.
new_date = d.at_beginning_of_week
if new_date < d
new_date = new_date.next_week
end

new_date
end

Hi Steven, thanks for your comment.

I appreciate you try doing that in ruby. I still have to study your code if it runs well.

Yeah, something happened both times on my copy and paste. The first time, a whole chunk of the end was left off. Next time, it looks like some other pieces were left out. Sorry about the $add remnant, I took it out.

here it is again.

function get_Xth_DOW($DOW,$X,$M,$Y) {
$numDays = date(’t',mktime(0,0,0,$M,1,$Y));
$add = 7*($X – 1);
$firstDOW = date(’w',mktime(0,0,0,$M,1,$Y));
$diff = $firstDOW – $DOW;
$d = 1;
if($diff > 0) { $d += (7 – $diff); }
else if ($diff $numDays) { $d -= 7; }
return $d;
}

Frick. I have to make it printable in HTML. Lets see if this comes out right.

function get_Xth_DOW($DOW,$X,$M,$Y) {
$numDays = date(’t',mktime(0,0,0,$M,1,$Y));
$add = 7*($X – 1);
$firstDOW = date(’w',mktime(0,0,0,$M,1,$Y));
$diff = $firstDOW – $DOW;
$d = 1;
if($diff > 0) { $d += (7 – $diff); }
else if ($diff < 0) { $d += -1*$diff; }
$d = $d + $add;
while($d > $numDays) { $d -= 7; }
return $d;
}

Leave a Reply

Flickr Photos

Getz IT at Mr. Choi Kitchen

Getz IT at Mr. Choi Kitchen

Twins Ba?

Twins Ba?

Twins Ba?

More Photos