I have this code that modify date in the way I want, for example, if starting date is 31/01/2000, adding 1 month will return 29/02/2000, then, 31/03/2000. If date is 30/01/2000 (not last day of the month) it will return 29/02/2000, then 30/03/2000, 30/04/2000 and so on.
I want to transfirm that code in a general case function, to be able to add 1,3,6,12 months, and inside the for loop, to work all corect. I would like it to be a function 2 or 3 arguments, startingDate, duration(nr of iterations), frequency (add 1/3/6/12 months per once).
<?php
$date = new DateTime('2000-01-28'); // or whatever
#echo $date->format('d')." ".$date->format('t');
$expectedDay = $date->format('d');
$month = $date->format('m');
$year = $date->format('Y');
for ($i = 0; $i < 100; $i++) {
echo $date->format('Y-m-d') . "<br>";
if ($month++ == 12) {
$year++;
$month = 1;
}
$date->modify("${year}-${month}-1");
if ($expectedDay > $date->format('t')) {
$day = $date->format('t');
} else {
$day = $expectedDay;
}
$date->modify("${year}-${month}-${day}");
}
Whelp, there's an extremely easy function for this in PHP nowadays.
first, you get a timestamp instead of a datetime:
$timestamp = $date->getTimestamp();
strtotime("+1 month", $myTimestamp);
You can change the +1 into anything you want, so you just throw the amount in the string and voila; a dynamic way of adding them!
however, since you want to do +30 days instead of a natural month, you're better off just adding 30 days to the timestamp, like so:
$timestamp = $timestamp + (3600 * 24 * 30); //s per h * h per d * d
So, you'd end up with something like this:
function calculateTime($startingDate, $iterations, $frequency){
$timeStamp = strtotime($startingDate);//if you expect a string date
$timeToAdd = (3600 * 24 * 30) * $frequency; //30 days * frequency
$return = array();
$return[] = date('Y-m-d', $timeStamp); //Original date
$previousDate = $timeStamp; //Original date for now
for($i = 0; $i < $iterations; $i++){
$newDate = $previousDate + (3600 * 24 * 30);
$return[] = date('Y-m-d', $newDate);
$previousDate = $newDate;
}
return $return;
}
And then for the rendering part:
//Let's render this stuff
$dates = calculateTime('24-08-2017', 25, 3);
foreach($dates as $date){
echo "$date</br>";
}
<?php
function calculateTime($startingDate, $iterations, $frequency){
$timeStamp = strtotime($startingDate);//if you expect a string date
$return = array();
$return[] = date('Y-m-d', $timeStamp); //Original date
$previousDate = $timeStamp; //Original date for now
for($i = 0; $i < $iterations; $i++){
$lastDay = false;
//It's the last day of the month
if(date('t', $timeStamp) == date('d', $timeStamp)){
$lastDay = true;
}
if($frequency == 12){
$newDate = strtotime('+1 year', $previousDate);
}
else{
if($lastDay){
$firstDayOfMonth = strtotime(date("01-m-Y", $previousDate));
$newDate =strtotime("+$frequency month", $firstDayOfMonth);
}
else{
$newDate = strtotime("+$frequency month", $previousDate);
}
}
if($lastDay){
$return[] = date('Y-m-t', $newDate);
}
else{
$return[] = date('Y-m-d', $newDate);
}
$previousDate = $newDate;
}
return $return;
}
//Let's render this stuff
$dates = calculateTime('31-01-2000', 25, 1);
foreach($dates as $date){
echo "$date</br>";
}
I hope this helps? :)
If you'd like to see how this works quickly, just paste my code into a phpfiddle. Unfortunately the save function is broken right now.