try the [man]DateTime[/man] class.

<?php

$date = new DateTime( '08-04-12' );  // start date 
//  !! (this format might not be interpreted correctly, however, based on your locale)
$interval = new DateTimeInterval( 'P6D' );  // 6 days
$date->sub( $interval );  // subtract 6 days

print $date->format( 'Y-m-d' );
    timstring wrote:

    I do not understand the '$strtotime' function well enough to get the desired outcome.

    The comment traq gives about "08-04-12" is related to this. That is a very poor way of representing dates, since there are at least three common ways of interpreting it: as 8 April 2012, 4 August 2012, or 12 April 2008 (assuming it refers to the 21st century); [man]strtotime[/man] takes the last interpretation. Much better is the form you convert it into (which is the industry standard): they should be stored that way to start with.

    Do you have any control over the format in which you receive the date?

      No, I have no control over the dates, except that the program producing my reports dumps the data into an Excel (egad) spreadsheet and I change the date format before I import the resultant 'CSV' file into my database. The dates are stored in MySQL as yyyy-mm-dd.

      Let me take a step back. The user enters the end date as the American standard m-d-yy, as instructed in the entry form. Manipulating that string into into the ISO format is relatively easy:

      		$ExpDate = (explode("-",$ReportDate));
      
      	$EndMonth = $ExpDate[0];
      	$EndDay = $ExpDate[1];
      	$EndYear = $ExpDate[2];
      	$ShortYear = $EndYear;
      
      	if($EndYear<2000) $EndYear = $EndYear + 2000;
      	if(strlen($EndMonth) < 2) $EndMonth = "0" . $EndMonth;
      	if(strlen($EndDay) < 2) $EndDay = "0" . $EndDate;
      
      
      	$EndDate = $EndYear . '-' . $EndMonth . '-' . $EndDay;

      The difference between $StartDate and $EndDate is 6 days. The problem is going calculating the intermediate dates from $StartDate to $EndDate if $StartDate happens to fall in the month, or even year, or, oh heavens, a leap day previous to the $EndDate.

        timstring;11021265 wrote:

        ...The user enters the end date as the American standard m-d-yy, as instructed in the entry form. Manipulating that string into into the ISO format is relatively easy

        ...but is insuring that the user entered the string correctly (e.g., you know that they meant August 4 and not April 8) also easy?

        In any case, if you can convert it reliably, then DateTime is a perfect solution. It takes all of the issues you mention (month breaks, leap days, etc.) into account.

        The example I gave omits the $timezone param, so will use your system's default. Since you are only considering dates (not times), and you're starting out with a date string, this might work out all right. I'd recommend setting the tz explicitly, however, for flexibility (and to avoid any future complications).

          traq;11021261 wrote:

          try the [man]DateTime[/man] class.

          <?php
          
          $date = new DateTime( '08-04-12' );  // start date 
          //  !! (this format might not be interpreted correctly, however, based on your locale)
          $interval = new DateTimeInterval( 'P6D' );  // 6 days
          $date->sub( $interval );  // subtract 6 days
          
          print $date->format( 'Y-m-d' );

          I copied and pasted your script into mine, and the server says "Fatal error: Class 'DateTimeInterval' not found in /Applications/XAMPP/xamppfiles/htdocs/WeeklyReport.php on line 208, which is the '$interval' formula. So, don't ask me why, but this did not have an error

          $date = new DateTime($EndDate);
          $date->sub(new DateInterval('P6D'));
          echo $date->format('Y-m-d') . "\n";

          This works, but again, don't ask me why. How, then, do I go from '$date->format(Y-m-d)" to an actual variable?

            timstring wrote:

            I copied and pasted your script into mine,

            Cut and paste code never works. Checking the manual, it should be [man]DateInterval[/man].

            How, then, do I go from '$date->format(Y-m-d)" to an actual variable?

            What does this mean? You want to know how to put a value into a variable?

              Weedpacket;11021281 wrote:

              Cut and paste code never works. Checking the manual, it should be [man]DateInterval[/man]

              .

              Funny, HaHa. You must be joking. You must be running Vista. I have been cutting and pasting on a Mac since 1987, and haven't had any problems other than operator error. I have never had a problem cutting and pasting code, even yours. I copied and pasted the script that worked from php.net.

              [QUOTE}What does this mean? You want to know how to put a value into a variable?[/QUOTE]

              I do believe that's what I asked. How do I get from

              $date->format('Y-m-d') . "\n";

              to

              $x = somefunction('$date->format('Y-m-d')) . "\n"';

              While I have your attention, how do I accomplish this?:

              for ($counter=1; $counter <= 7; $counter++)
              				{
              					$date = new DateTime($EndDate);
              
              				$test = "('P" . $counter . "D')";
              				echo $date->sub(new DateInterval($test);
              				echo $date->format('Y-m-d') . "\n";
              
              			}

              Thanks for the help,
              tim

                what weedpacket is implying (and he's correct) is that I made a typo. The name of the class is [man]DateInterval[/man].

                As for how to set the value in a variable, you'd do it just like normal:

                $x = $date->format( 'Y-m-d' );

                $x would hold the string "2012-08-04", of course, not the date object itself. I don't know if that's what you wanted or not.

                for your loop, you don't need to increment the interval, since [man]datetime.sub[/man] changes the date in $date. e.g.,

                $date = new DateTime( '2012-08-04' );
                $oneday = new DateInterval( 'P1D' );
                print $date->sub( $oneday )->format( 'Y-m-d' );  // prints "2012-08-03"
                print $date->sub( $oneday )->format( 'Y-m-d' );  // prints "2012-08-02"
                //  . . . etc.
                  traq;11021303 wrote:

                  what weedpacket is implying (and he's correct) is that I made a typo. The name of the class is [man]DateInterval[/man].

                  I am so near-sited, both mentally and visually, that I didn't make the connection

                  As for how to set the value in a variable, you'd do it just like normal:

                  $x = $date->format( 'Y-m-d' );

                  $x would hold the string "2012-08-04", of course, not the date object itself. I don't know if that's what you wanted or not.

                  for your loop, you don't need to increment the interval, since [man]datetime.sub[/man] changes the date in $date. e.g.,

                  $date = new DateTime( '2012-08-04' );
                  $oneday = new DateInterval( 'P1D' );
                  print $date->sub( $oneday )->format( 'Y-m-d' );  // prints "2012-08-03"
                  print $date->sub( $oneday )->format( 'Y-m-d' );  // prints "2012-08-02"
                  //  . . . etc.

                  I do need the counter because I'm not only figuring the date, I'm constructing an array with the counter, too. Also, it condenses 8 lines of code down to 4.

                  Here's what I blundered into:

                  for ($counter=0; $counter <= 6; $counter++)
                  				{
                  					$date = date_create($EndDate);
                  					date_sub($date, date_interval_create_from_date_string($counter . 'days'));
                  					$IncDate = date_format($date, 'Y-m-d');
                  
                  
                  
                  				$Quest = "SELECT * FROM `$System` WHERE TechNum = '$TechNum' && WorkDate = '$IncDate'";
                  				$result = mysql_query($Quest, $cxn)
                  					or die ('the bear went over the mountain  ' . mysql_error());
                  
                  
                  ..more code..
                  ..more code...
                  
                                                 }

                  Doing this eliminated 18 lines of code:

                  for ($counter=0; $counter <= 6; $counter++)
                  				{
                  					$date = date_create($EndDate);
                  					date_sub($date, date_interval_create_from_date_string($counter . 'days'));
                  					$W["$counter"] = date_format($date, "D");
                  					$D["$counter"] = date_format($date, "n-j");
                  					echo $counter . ' ** ' . $W["$counter"] . ' ## ' . $D["$counter"] . '<br>';
                  				}		
                  
                  ..more code..more code
                  
                  for ($counter=0; $counter<=6; $counter++)
                  		   	     {
                  				  echo '<th style = "width:40px">'  . $W["$counter"] . '<br>' . $D["$counter"] . '</th>';
                  			     }

                  Thanks very much for the hints. They pointed me where I needed to go.

                    timstring wrote:

                    haven't had any problems

                    You cut and posted code from here and had a problem.

                    other than operator error

                    And that's why you had a problem.

                    Copying a piece of code without reading it to understand what it even does (let alone verify that it does what you even want), and not checking for any typos that it may contain.

                      ...I didn't suggest you didn't need the counter; I said you didn't need to increment the date interval. You can simply put that one call to $date->sub() in the loop for however many iterations you like.

                      Aside from that, however, can I ask if you're trying to find records within a certain date range? If so, you're following the wrong approach.

                      Is [font=monospace]WorkDate[/font] a [font=monospace]DATETIME[/font] field?

                      SELECT whatever FROM table WHERE WorkDate BETWEEN {start} AND {end}
                        Write a Reply...