Hey guys,

I am a quite experienced developer but I just cannot wrap my head around an easy way to do the following.

I am writing code for a client that has a five digit code which represents when it's branch offices need to test. I am easily able to break this code down into a readable format, ie: "The second thursday of June, and November." The client however would like me to break this down even further and have it determine what date the second thursday of june and november may actually be. I'd rather not have to make a huge array with every date of the year in it.

Can anyone think of a simpler solution?

Thanks,

Brian

    Too vague for a clear-cut answer, but

    echo date('Y-m-d', strtotime('2 Thursday', strtotime('1 November')));

    Is the first thing I think of. Suffice it to say that PHP has plenty of date and time calculation functions that it shouldn't be necessary to store an array with every day of the year for what would have to be fourteen years.

      hey, great, that's actually exactly what i need however there is 1 problem.

      it's a day off. 2nd thurs shows as the 12th and should be the 13th. 3rd shows as the 19th and not the 20th. i assume this is going to be a server related issue?

        That's a "feature" of the underlying C library. (The "off by one week or day problem", I guess it would be called.) Something like this should do it:

        $num_thu = 2;
        $start_ts = strtotime('1 November');
        if (date('D', $start_ts) != 'Thu') {
            $start_ts = strtotime('last Thursday', $start_ts);
        } else {
            $num_thu -= 1;
        }
        $num_thu_ts = strtotime('+' . $num_thu . ' weeks', $start_ts);

          that works fantastic, however when i try to implement as a dynamic thing (ie can be any day, of any week, of any month) it doesn't give correct dates.

          I am fetching the correct month, in $mo1. It's fully spelled out, ie: January.

          Correct week is being fetched in $week. It's numerical, ie: 1

          Fetching the correct day with $day. Fully spelled out, ie: Monday

          I am also fetching the correct day in $dayShortened. It's shortened to comply with the date function, ie: Mon

          But when I execute this code, I get an incorrect date.

          $num_day_1 = $week; 
          $start_ts_1 = strtotime('1 $mo1 $currentYear'); 
          if (date('D', $start_ts_1) != '$dayShortened') { 
              $start_ts_1 = strtotime('last $day', $start_ts_1); 
          } else { 
              $num_day_1 -= 1; 
          } 
          $mo1_date = strtotime('+' . $num_day_1 . ' weeks', $start_ts_1);
          
          $mo1_date_processed = date('d', $mo1_date);
          

            At a glance, '$daysShortened[($tcChar[5]-1)]' should be $daysShortened[($tcChar[5]-1)].

              i fixed all the variables that were incorrectly encapsed. but the day is still off by several days.

                Mind posting your current code, test input, actual test output, and expected test output?

                  absolutely.

                  $tcChar = preg_split('//', $testcode, -1);
                  
                  if($tcChar[1] == '1')
                  {
                  	$mo1 = $qtr1[($tcChar[3]-1)];
                  	$mo2 = $qtr3[($tcChar[3]-1)];
                  } else
                  {
                  	$mo1 = $qtr2[($tcChar[3]-1)];
                  	$mo2 = $qtr4[($tcChar[3]-1)];
                  }
                  
                  $week = $tcChar[4];
                  $day = $days[($tcChar[5]-1)];
                  $dayShortened = $daysShortened[($tcChar[5]-1)];
                  
                  if($week == "1") {
                  $phoneticWeek = "1st";
                  } else if($week == "2") {
                  $phoneticWeek = "2nd";
                  } else if($week == "3") {
                  $phoneticWeek = "3rd";
                  } else if($week == "4") {
                  $phoneticWeek = "4th";
                  } else if($week == "5") {
                  $phoneticWeek = "5th";
                  }
                  
                  echo "<td>";
                  echo "<center>$phoneticWeek $day of $mo1 and $mo2</center>";
                  echo "</td>";
                  
                  $num_day_1 = $week; 
                  $start_ts_1 = strtotime('1 ' . $mo1 . ' ' . $currentYear); 
                  if (date('D', $start_ts_1) != $dayShortened) { 
                      $start_ts_1 = strtotime('last' . $day, $start_ts_1); 
                  } else { 
                      $num_day_1 -= 1; 
                  } 
                  $mo1_date = strtotime('+' . $num_day_1 . ' weeks', $start_ts_1);
                  
                  $mo1_date_processed = date('d', $mo1_date);
                  
                  echo "<td>";
                  echo "<center>$mo1 $mo1_date_processed $currentYear</center>";
                  echo "</td>";
                  

                  the input is a 5-digit test code. first 2 digits are quarters, 3rd digit is month of the quarter, 4th digit is week of the month, and 5th digit is day of the week.

                  The "testcode" i am putting in for this test run is "24343". The output correctly shows that the testing quarters would be "4th Wednesday of June and December of 2009"

                  For the specific date it is returning June 28th, 2009, which isn't correct. It should be showing June 24th, 2009.

                    hmm... the problem seems interesting enough, so I would like to propose an entirely different solution:

                    <?php
                    
                    function testCodeToTimes($testcode, $year = 2008)
                    {
                        static $day_names = array('monday', 'tuesday', 'wednesday', 'thursday',
                            'friday', 'saturday', 'sunday');
                        static $week_numbers = array('first', 'second', 'third', 'fourth', 'fifth');
                        static $month_names = array('jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul',
                            'aug', 'sep', 'oct', 'nov', 'dec');
                    
                    $base_month = $testcode[2];
                    $base_day = $week_numbers[$testcode[3] - 1] . ' '
                        . $day_names[$testcode[4] - 1] . ' ';
                    
                    $month = 3 * ($testcode[0] - 1) + $base_month - 1;
                    $test_times[] = strtotime($base_day . $month_names[$month] . ' ' . $year);
                    
                    $month = 3 * ($testcode[1] - 1) + $base_month - 1;
                    $test_times[] = strtotime($base_day . $month_names[$month] . ' ' . $year);
                    
                    return $test_times;
                    }
                    
                    $test_times = testCodeToTimes("24343", 2009);
                    
                    echo date('l, F jS, Y', $test_times[0]) . "<br \n>"
                        . date('l, F jS, Y', $test_times[1]);
                    
                    ?>

                    My idea is to change the test code string like "24343" into "fourth wednesday june 2009" and "fourth wednesday december 2009", and then use strtotime() to convert them into a timestamp, upon which you have more options for formatting.

                      do you get the right output for that? even as you stated it should be parsing the 4th wednesday in both june and december. however my output is:

                      Sunday, June 21st, 2009
                      Monday, December 21st, 2009

                      I find it strange that both of the dates are the 21st. I wonder if this could be an issue with my server, unless that produces the same output for you.

                        brbourdo wrote:

                        I wonder if this could be an issue with my server, unless that produces the same output for you.

                        It produces the correct output for me, so maybe the problem is with your server (unless it is with mine and my proposed script instead).

                          i am indeed using your script, completely unedited aswell. i have opened a ticket with my hosting company. i hope this is something they can resolve.

                            my host refuses to acknowledge this as an issue, even though it very clearly is. i tried to tell them it worked on a different web server but haven't gotten a response.

                            another interesting behavior has happened aswell.

                            yesterday it produced the result as being the 21st of June, and December on my server. Today it's showing the 22nd as the result. This is blatantly a server side issue.

                            Any ideas on how I might be able to get through to them?

                              brbourdo wrote:

                              another interesting behavior has happened aswell.

                              yesterday it produced the result as being the 21st of June, and December on my server. Today it's showing the 22nd as the result. This is blatantly a server side issue.

                              hmm... I briefly toyed with the possibility that it is a bug due to strtotime() accepting a second argument, namely the current time from which to base the computed time. However, the time string is absolute, so it does not matter what that second argument is, thus it looks like the problem really is with the server.

                              brbourdo wrote:

                              Any ideas on how I might be able to get through to them?

                              Maybe just show them this example:

                              echo date('l, F jS, Y', strtotime('fourth wednesday june 2009'));

                              Then point out that obviously neither the 21st nor the 22nd of June 2009 is a Wednesday, so the server is reporting the wrong date for the fourth Wednesday of June 2009.

                                i guess im just not gonna be able to get this to work. the host refuses to assist and is telling me the code is causing the problem.

                                thanks anyways laserlight, i really appreciate the assistance you've given me.

                                  That's sad, maybe you should change to a different host 🙂

                                    Write a Reply...