Determining the first available date off (next week)

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
plezops
Forum Newbie
Posts: 11
Joined: Mon May 28, 2007 5:22 pm
Location: Austin, Texas

Determining the first available date off (next week)

Post by plezops »

I am currently working on a project and have almost everything else completed... for some reason I can not get my head or my code (I can get it to work a little...) to work for this part. I think I have been staring at my computer screens for too long. :P

Description of problem and what I am trying to accomplish:
I need to find the first available date off for an employee who is requesting a day off. All requests for the next week must be made my the preceding Wednesday at 5:00 PM. I would like to pass today's date (timestamp) to a function and have it return the next available date for requests.
Example: (today's date -> before this Wednesday at 5 (bool) -> returns first available date)
4:00 PM Monday October 19, 2009 -> true -> Monday October 26, 2009
12:30 PM Wednesday October 21, 2009 -> true -> Monday October 26, 2009
5:30 PM Wednesday October 21, 2009 -> false-> Monday November 2, 2009
9:00 AM Thursday October 22, 2009 - > false -> Monday November 2, 2009

Some code I have... I think it works okay (only tested a few days) but it isn't in the format, as it only returns the difference between dates) I would like and it doesn't check the time.

Code: Select all

// todays date
        $today = date('Y-m-d');
    // next monday
    // first available day to request off
    // if today is <7 days from monday get next +7
        $nextMon = date('Y-m-d', strtotime('next Monday')); 
        $difference = daysDifference($today, $nextMon);
        if($difference <=7){
            $difference+=7;
        }
    
    function daysDifference($beginDate, $endDate){
       //explode the date by "-" and storing to array
       $date_parts1=explode("-", $beginDate);
       $date_parts2=explode("-", $endDate);
       //gregoriantojd() Converts a Gregorian date to Julian Day Count
       $start_date=gregoriantojd($date_parts1[1], $date_parts1[2], $date_parts1[0]);
       $end_date=gregoriantojd($date_parts2[1], $date_parts2[2], $date_parts2[0]);
       return $end_date - $start_date;
    }
Any help would be extremely appreciated.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: Determining the first available date off (next week)

Post by califdon »

I would try this (I haven't tested it, but it's easy to understand, I think):

Code: Select all

function nextavaildayoff() {
   $dow=date('w');
   $tmp=strtotime('next Monday');
   switch ($dow) (
      case 0 :  // Sun
      case 1 :  // Mon
      case 2 :  // Tue
         return $tmp;
         break;
      case 3 :  // today is Wed
         if(date('G') < 12) {
            return $tmp;
         } else {
            return strtotime('+1 week', $tmp);
         }
         break;
      case default :  // today is Thur/Fri/Sat
         return strtotime('+1 week', $tmp);
   }
}
[Edit]: This is probably even simpler, now that I look at it again:

Code: Select all

function nextavaildayoff() {
   $dow=date('w');
   $tmp=strtotime('next Monday');
   if(($dow < 3) || ($dow == 3 && date('G') < 12) {
      // today is either Sun/Mon/Tue or Wed-before-noon:
      return $tmp;
   } else {
      return strtotime('+1 week', $tmp);
   }
}
Last edited by califdon on Mon Oct 19, 2009 1:24 pm, edited 1 time in total.
Reason: even simpler code
plezops
Forum Newbie
Posts: 11
Joined: Mon May 28, 2007 5:22 pm
Location: Austin, Texas

Re: Determining the first available date off (next week)

Post by plezops »

Thanks a bunch califdon, I have no idea why I couldn't get this... Here is my working code from your first example. I am going to take a look at the second snippet you provided and see if that would work (it looks like it should).

I changed the code you provided to take either a timestamp or a given date as an argument (a requirement to help another function print future paper request sheets if needed). Also Sunday should be included with the 'default case'. For anyone else that this might help, the reason being is that the next Monday of a Sunday is tomorrow, and it would return tomorrow as the first available day off when it should be the next, next Monday. So, everything that is this week and before Wednesday at 5:00 PM should go to the next Monday; everything after (and the current weeks Sunday) Wednesday at 5:00 PM should go to the second Monday. (The code/examples makes more sense than this might :P)

Thanks for the help califdon!

Code: Select all

date_default_timezone_set('US/Central');
 
function nextAvailDayOff($dateString) {
    // $now must be timestamp or be in the following format
    // 'Y-m-d H:i' or 'Y-m-d g:i a'
    //> almost all dates passed through should work as long
    //> as they include the date and hour
    
    if(strtotime($dateString)){
        // strtotime worked, date in string format
        $now = strtotime($dateString);   
    } else if(1 === preg_match( '~^[1-9][0-9]*$~', $dateString )){
        // strtotime failed, date in timestamp format
        $now = $dateString; 
    } else {
        // not a valid timestamp, unacceptable format
        return 0;
    }
    
    $day = date('w', $now);     // Sunday = 0
    $hour = date('H', $now);    // Military time
 
    $tmp=strtotime('next Monday', $now);
    switch ($day) {
                // Sunday must be a default case otherwise
                // it returns tomorrow as the next available
        case 1: // Mon
        case 2: // Tue
            return $tmp;
            break;
            
        case 3: // Wed
                // after 5 PM - 24 hour clock
            if($hour < 17) {
                return $tmp;
            } else {
                return strtotime('+1 week', $tmp);
            }
            break;
            
        default :  // Sun / Thu / Fri / Sat
            return strtotime('+1 week', $tmp);
    }
}
 
#############################################
## EXAMPLES AND TESTING ######################
#############################################
 
// time() = Monday October 19, 2009 at 01:30 AM
// Monday October 19, 2009 -> Monday October 26, 2009
$date = time();
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Sunday November 01, 2009 -> Monday November 09, 2009
$date = '2009-11-01 01:50 PM';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Monday November 02, 2009 -> Monday November 09, 2009
$date = '2009-11-02 06:25';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Tuesday November 03, 2009 -> Monday November 09, 2009
$date = '2009-11-03 05:50 PM';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Wednesday November 04, 2009 at 04:00 PM -> Monday November 09, 2009
$date = '2009-11-04 16:00';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Wednesday November 04, 2009 at 05:01 PM -> Monday November 16, 2009
$date = '2009-11-04 17:01';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Thursday November 05, 2009 -> Monday November 16, 2009
$date = '2009-11-05 01:42 AM';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Friday November 06, 2009 -> Monday November 16, 2009
$date = '2009-11-06 13:15';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// Saturday November 07, 2009 -> Monday November 16, 2009
$date = '2009-11-07 11:36 AM';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
 
// This is not a date! -> Wednesday December 31, 1969
$date = 'This is not a date!';
echo "$date -> ".date('l F d, Y', nextAvailDayOff($date))."<br />";
Post Reply