Figure out Thurday meeting dates

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Technocrat
Forum Contributor
Posts: 127
Joined: Thu Oct 20, 2005 7:01 pm

Figure out Thurday meeting dates

Post by Technocrat »

So we have meetings every other Thursday and I would like to figure out the next three dates dates for them. I have the following code which works except it skips to the next Thursday if today is one of the meeting dates. So how can I keep it from skipping when it's Thursday? Is there a better code for this?

Code: Select all

function getMeeting($which_date) {
	//1294300800 Jan-6-2011
	$next = strtotime("next Thursday");
	$diff = round(($next - 1294300800) / 86400);
	if (($diff % 14) == 0) {
		$date = $next;
	} else {
		$date = strtotime("next Thursday", $next);
	}
	if $which_date == 0) {
		return date('l, F j, Y', $date);
	} else if ($which_date == 1) {
		$date = strtotime("+3 Thursday", $date);
		return date('l, F j, Y', $date);
	} else if ($which_date == 2) {
		$date = strtotime("+5 Thursday", $date);
		return date('l, F j, Y', $date);
	}
	return date('l, F j, Y', $date);
}
User avatar
twinedev
Forum Regular
Posts: 984
Joined: Tue Sep 28, 2010 11:41 am
Location: Columbus, Ohio

Re: Figure out Thurday meeting dates

Post by twinedev »

A little different approach for ya:

Code: Select all

<?php

	function GetMeeting($whichWeek,$strFormat = 'l, F j, Y') {

		static $aryMeetings = array();

		$intNumMeetings = count($aryMeetings);

		if ($intNumMeetings == 0) {

			// First Time Call, build up an array of upcoming dates

			// BEGIN: CONFIGURATION - Adjust these as needed
				$intMeetingDayOfWeek = 4; // 0=Sun, 1=Mon, 2=Tues, 3=Wed, 4=Thur, 5=Fri, 6=Sat
				$intNumMeetings = 3;
				$intWeekOffset = 0; // Toggle this between 0 and 1 to find the correct set of weeks
			// END: CONFIGURATION - Adjust these as needed

			list($DayOfWeek,$intMonth,$intDay,$intYear) = explode("-",date('w-m-d-Y'));

			$tsToday = mktime(0,0,0,$intMonth,$intDay,$intYear);

			$intDayOffset = 60 * 60 * 25; // NOTE: 25 was used on purpose, see notes to why.

			if ($DayOfWeek <= $intMeetingDayOfWeek) {
				$intDaysTillThursday = ($intMeetingDayOfWeek-$DayOfWeek);
			}
			else {
				$intDaysTillThursday = ((7+$intMeetingDayOfWeek)-$DayOfWeek);
			}

			$tsThurday = $tsToday + $intDayOffset * $intDaysTillThursday;

			$WeekOfYear = date('W',$tsThurday);
			if ($WeekOfYear % 2 == $intWeekOffset) {
				// The meeting isn't this week, so skip to next week
				$tsThurday += $intDayOffset * 7;
			}

			// We have first Thursday to use, loop through
			for ($t = 0; $t < $intNumMeetings; $t++) {

				// Becasue offsets adds one hour, lets get it back to midnight of the date
				list($intMonth,$intDay,$intYear) = explode("-",date('m-d-Y',$tsThurday));
				$tsThurday = mktime(0,0,0,$intMonth,$intDay,$intYear);

				$aryMeetings[] = $tsThurday;

				$tsThurday += $intDayOffset * 14; // Advance to the next Thursday

			}
		}

		if ($whichWeek < $intNumMeetings) {
			return date($strFormat,$aryMeetings[$whichWeek]);
		}
		else {
			return '[ERR: Week Number out of Range]';
		}
	}
	// END: function GetMeeting($whichWeek,$strFormat = 'l, F j, Y')


// LETS TEST IT OUT!

for($t=0;$t<5;$t++) {
	echo $t,' = ',GetMeeting($t),"<br>\n";
}

?>
I broke it out a little more than if it was code I was using to make it a little more readable.

In the function, there are three lines that you need to adjust to configure when your meetings are. There are explained in the notes. The third one, leave alone at first, if you are geting the wrong weeks, change it to a 1

You may notice that in the code, to calculate a full day, I'm using 25 hours instead of 24. This was done on purpose to handle if the ending of Daylight Savings Time occurs sometime between now and end of the list of meetings (that day there is actually 25 hours that day if the timezone of the server is set to recognizes them). Since we don't care what hour of the day it is, technically if you add 5 days, to Midnight, August 8, 2011, you would get 5:00am, August 13, 2011, the code will round it back to midnight for ya. (This trick is safe, as long as you are never adding more than 22 days before rounding back to midnight (entering Daylight Savings time technically has just 23 hours that day).

To see an example of what I mean by the above, try changing it back to 24, and then adjust number of weeks to calculate (and display) to be 26 (to get a years worth) you would see something like this:

[text]4 = Thursday, October 13, 2011
5 = Thursday, October 27, 2011
6 = Wednesday, November 9, 2011
7 = Wednesday, November 23, 2011[/text]

This is because only using 24 hours a day, when it went to calculate Thursday, Nov 10, you actually ended up with 11:00pm, Wed, Nov 9th, which is obviously not a Thursday. Using the 25 hours for offset gets you 7:00am, Thurs, Nov 10th, which is the correct date. (and time gets reset back to midnight before being stored and using during next run through loop.)

I prefer this method over other functions, as there is less for for it to do when you are just working with integers instead of code that had to figure out what "next Thursday" means. As long as it is coded solid, works just fine.

-Greg
User avatar
Technocrat
Forum Contributor
Posts: 127
Joined: Thu Oct 20, 2005 7:01 pm

Re: Figure out Thurday meeting dates

Post by Technocrat »

Perfect! Thanks so much
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: Figure out Thurday meeting dates

Post by califdon »

@twinedev: Excellent algorithm and explanation! I have written several 'regular schedule' algorithms somewhat like this, but yours handles exceptions more reliably than mine. Thanks.
User avatar
twinedev
Forum Regular
Posts: 984
Joined: Tue Sep 28, 2010 11:41 am
Location: Columbus, Ohio

Re: Figure out Thurday meeting dates

Post by twinedev »

Glad to help, I love to figure things like that out :-)
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Figure out Thurday meeting dates

Post by pickle »

~twinedev's solution seems much more complex than necessary, to do something strtotime() should do for you automatically

I'm assuming $which_date can have a value of 0,1,2 if you want to return the next meeting, the one after that, or the one after that respectively.

Code: Select all

function getMeeting($which, $format = 'l, F j, Y')
{	
	# if today is Thursday
	$next = (date('N') == 4)
		# Start from today's date
		? time()
		# Otherwise start from the next Thursday
		: strtotime('next Thursday');
	
	# Add however many weeks is necessary (including 0)
	$date = strtotime('+'.$which.' week',$next);
	
	# Format & return
	return date($format,$date);
}
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
twinedev
Forum Regular
Posts: 984
Joined: Tue Sep 28, 2010 11:41 am
Location: Columbus, Ohio

Re: Figure out Thurday meeting dates

Post by twinedev »

Mine came from scheduling code that was designed to keep repeating, so I just grabbed and modified it to fit the function, but I agree Pickle's code is much simpler!

-Greg
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Figure out Thurday meeting dates

Post by pickle »

Ah - that makes sense.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
Technocrat
Forum Contributor
Posts: 127
Joined: Thu Oct 20, 2005 7:01 pm

Re: Figure out Thurday meeting dates

Post by Technocrat »

Problem is I don't just need to know the Thursdays I need to every other Thursday. So Pickle's code doesn't take that into account.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Figure out Thurday meeting dates

Post by pickle »

So multiply by 2:

Code: Select all

function getMeeting($which, $format = 'l, F j, Y')
{      
        # if today is Thursday
        $next = (date('N') == 4)
                # Start from today's date
                ? time()
                # Otherwise start from the next Thursday
                : strtotime('next Thursday');
       
        # Add however many weeks is necessary (including 0)
        $date = strtotime('+'.($which*2).' week',$next);
       
        # Format & return
        return date($format,$date);
}
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: Figure out Thurday meeting dates

Post by califdon »

Technocrat wrote:Problem is I don't just need to know the Thursdays I need to every other Thursday. So Pickle's code doesn't take that into account.
Actually it will if you slightly modify it to say "+2 week" instead of "week". Check out http://stringtotime.com/
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: Figure out Thurday meeting dates

Post by McInfo »

I think the best performance can be achieved by picking dates out of a hard-coded array. Problems are: it can make your code look bloated; it will continue to work only if you update the code every few years; and if you include too many dates, the advantage is lost (but is your code really going to survive until 2038?).
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: Figure out Thurday meeting dates

Post by califdon »

McInfo wrote:I think the best performance can be achieved by picking dates out of a hard-coded array. Problems are: it can make your code look bloated; it will continue to work only if you update the code every few years; and if you include too many dates, the advantage is lost (but is your code really going to survive until 2038?).
No doubt that's technically true, but I think the performance gain would be unmeasurable in a practical situation. I would probably use strtotime(), as Pickle suggested.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: Figure out Thurday meeting dates

Post by McInfo »

califdon wrote:No doubt that's technically true, but I think the performance gain would be unmeasurable in a practical situation. I would probably use strtotime(), as Pickle suggested.
My first instinct is to use strtotime(), too. I was just throwing the caching idea out there. This is an interesting problem and I've spent a lot of time (probably too much) investigating different strategies.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: Figure out Thurday meeting dates

Post by califdon »

McInfo wrote:My first instinct is to use strtotime(), too. I was just throwing the caching idea out there. This is an interesting problem and I've spent a lot of time (probably too much) investigating different strategies.
I know how you feel! :wink:
Post Reply