Page 1 of 1

Determining the first available date off (next week)

Posted: Sun Oct 18, 2009 11:21 pm
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.

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

Posted: Mon Oct 19, 2009 12:07 am
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);
   }
}

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

Posted: Tue Oct 20, 2009 12:19 am
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 />";