Previous next date code keeps causing browser to crash

I have a previous next code that jumps ahead or behind in time by a week. I’m not sure what I have done wrong, it works but if I try go more than a few clicks back or forward, it just loads and loads and eventually I have to restart my browser and Xampp.
Here is my code:

<?php
	$currentDate = date('Y-m-d');
	$oneWeek = date('Y-m-d',strtotime($currentDate."+7 days"));
//604800 one week in strtotime


	
if(!empty($_GET['oneWeek'])) {
	$oneWeek = $_GET['oneWeek'];
	$currentDate = $_GET['currentDate'];
}
	?>

	<a href="?currentDate=<?php echo date('Y-m-d',strtotime($currentDate.'-7 days')); ?>&oneWeek=<?php echo $currentDate; ?>">Previous week</a>
	<a href="?currentDate=<?php echo date('Y-m-d',strtotime($currentDate.'+7 days')); ?>&oneWeek=<?php echo date('Y-m-d',strtotime($currentDate.'+14 days')); ?>">Next week</a>
	
 .........

do { ?>
			<tr>
				<th>
					<?php 
					$niceDate = date('d M Y, D', strtotime($currentDate));
					echo $niceDate; ?>
				</th>
.......

			<?php
			$currentDate++;
		} while ($currentDate <= $oneWeek);

I’ve omitted part of the code to show where it starts up again within the do while statement. I included that part because I am not sure if that is causing my browser to crash.

Then, if the page does eventually load, the dates go back to 01 jan 1970 at the end of the year:

And same issue here when going back in time:

But you left off the ‘while’ part of the do-while, so we don’t know what the trigger for your loop to end is. :stuck_out_tongue:

m_hutley, just added it into my code example now.

I am honestly surprised your code works at all given that input.

$currentDate is a string. String++ makes no logical sense.

If you want to manipulate $currentDate as a Date, form a DateTime object from it and manipulate it correctly.

I wondered about that, but a quick bit of dirty code

$currentDate = date('Y-m-d');

echo $currentDate . " " ;
$currentDate++;
echo $currentDate;

suggests that it does give the required information, somehow:

2019-12-09 2019-12-10

@droopsnoot: And I notice his problems all stem from month boundaries. What happens when you give it the last day of a month and tell it to ++?

My suspicion is that it’s treating 2019-12-09 as an oddball form Integer (with - separators), and doing INT manipulation, which would result in ++ giving 2019-12-32 , which strtotime would reject, and return 0 (or Jan 1, 1970…)

EDIT: Have confirmed my suspicion:

<?php
$string = "2019-12-31";
echo ++$string;
var_dump(strtotime($string));
?>

Result:
2019-12-32bool(false) (okay so i didnt make it pretty.)

Ok, so if I change everything out to a unix time stamp, and then run the $currentDate++ which will now be a string number, will that work?

Well it would, but if you do a unix timestamp and tell it to ++, you’ve added a second, not a day.

If you make it a DateTime, and then do $currentDate->modify("+1 day");, you should get a working object, which you can then call $currentDate->format("d M Y, D"); on, to get your output.

Like everyone else is saying - why are you not just using the methods which are built into the date object?

$currentDate->add(new DateInterval('P1D'));    // P1D = Period 1 day

https://www.php.net/manual/en/datetime.add.php

None of the suggestions above have worked for me, or I have implemented them incorrectly. I don’t know how to even start implementing date time, there is just that one page resource for it and it doesn’t show what you do with it. The new Dateinterval does the same things and hang as before. Please could someone perhaps provide a coded suggestion, because I am just not getting this and I have to restart my computer with every try!

In my experience, there are two common causes of a script timing out. 1. It’s trying to work with much more data than it should. i.e. pushing the limits of the language. 2. the script is caught in a loop it can’t get out of.

I suggest the first thing you do is strip the code down to the barest minimum needed to debug. in particular, temporarily lose the loop, and make sure you can get it to work for one echo.

Once that is working, temporarily change the code so you can tell what the values of what will be used in the conditional tests are. i.e. $currentDate and $oneWeek

Once you know those are good, remove (or comment out) the test lines of code and put the loop back.

2 Likes

Hi, I already did all that to create this whole thing in the first place, and it worked fine until i went a bit far back or forward in time. I’m starting again using a different page and will build again from there using unix timestamp values now only, and then only convert to y-m-d at the last. Hopefully this works now.

I’m trying to see if I can change the increment of a do while loop to 86400 which is one day instead of 1, does anyone know if this is possible? Or has anyone got a code example? oh wait, I just figured that out …

do {
    echo "The number is: $oneDay <br>";
    $oneDay+=86400;
} while ($oneDay <= 604800);

You are over complicating this and doing work that you should be getting the computer to do for you.

Your goal is to do date math, adding one day to the current date. The only change to the existing code is the line that’s currently doing $currentDate++; One such solution would be -

$currentDate = date('Y-m-d',strtotime($currentDate.'+1 days'));

As a separate issue, something tells me you are executing an sql query inside of this loop. Don’t. It is extremely inefficient to run SELECT queries inside of loops. You should instead run one query that gets the data BETWEEN the submitted start and end date. You would then fetch this data into a php array, indexing it by the date value. To produce the output grid, you would loop from the start date to the end date, testing if there is fetched data, via the array index, matching the current date being displayed.

I can’t say i particularly find the value in strtotiming something into an int to write it as a string, just for the purposes of strtotiming that string again to write it out as a slightly different string, but it would work.

I think you should do it again. In particular, look at $currentDate

I think you will probably need an outer conditional

This bit of code

			$currentDate++;
		} while ($currentDate <= $oneWeek); 

should become less problematic after the above is taken care of. Just the same, it might be a good idea to refresh yourself with something so “beginner” level it’s easy to pass it by. i.e.
https://www.php.net/manual/en/language.operators.increment.php

… Decrementing NULL values has no effect too, but incrementing them results in 1

Like they said, double check all your inputs because this little snippet of code loops in both directions…

<?php

// One Week in the Past
$currentDate = new DateTime('09-12-2019');
$oneWeekPrior = new DateTime('02-12-2019');
do { 
	echo $currentDate->format('d, M, Y, D');
	$currentDate->sub(new DateInterval("P1D"));
} while ($currentDate >= $oneWeekPrior);

// One Week in the Future
$currentDate = new DateTime('09-12-2019');
$oneWeekHence = new DateTime('16-12-2019');
do { 
	echo $currentDate->format('d, M, Y, D');
	$currentDate->add(new DateInterval("P1D"));
} while ($currentDate <= $oneWeekPrior);

Sounds like a prime candidate for DatePeriod to me:

$start = new DateTimeImmutable('09-12-2019');
$period = new DatePeriod($start, new DateInterval('P1D'), $start->modify('+7 day'));
foreach ($period as $date) {
    echo $date->format('d, M, Y, D');
}

Hi everyone, thank you so much for all your comments, it is so great to wake up to all this help this morning!

So I have felt very confused about using datetime, and there is limited online resources on how to use it as a coded example and $currentDate just was causing so many issues that I changed everything to unix numbers, and manually added seconds for days so that there can be no odd date issues and my previous and next code is working perfectly now. I didn’t get php to ‘work’ for me, but honestly, I don’t know how to implement alot of what was suggested. I would have to see a piece of code to understand it properly.

The one thing I do get is the need to not have the select statement within the loop and to take that out and create arrays out of it that can be accessed. I get the theory, but the actual implementation I will need an example, which hopefully one day I will come across. I think it involves doing something like this, but I am not sure:

// select statement here
//while ...
$bookings[] = $row['bookings'];
//... end while

foreach($bookings as $value){
  echo "Booking: $value<br>";
}

And then it can also be accessed with :

$booking[0];
$booking[1];

which could be put into a for loop to iterate through them all. Is that correct?

Want to bet? If your server is in a location that uses Daylight Savings Time, there are two days a year that don’t have 86400 seconds in them and someone accessing a site using this method will get an incorrect date result if doing so within an hour of midnight on those days. The date math examples that were posted using 1 day intervals (using date/strtotime or the date object) take DST into account (depending on php version, if the time-zone database that php is using is up to date, and if the server’s clock and time-zone are set correctly.)

To index/pivot the data using the date, you would use -

// for a single data item per date -
$bookings[$row['column holding the date']] = $row['bookings'];

// if there can be a set of data items per date -
$bookings[$row['column holding the date']][] = $row['bookings'];

In the code producing the output grid, you would take the current date being displayed, in a Y-m-d format, and test if there is an element set in the $bookings array -

// assuming you have a Y-m-d formatted value in $currentDate
if(isset($bookings[$currentDate]))
{
    // there is data for the $currentDate. reference it via $bookings[$currentDate]
}