This question already has answers here:
PHP: Populating an array with the names of the next 12 months
(8 answers)
Closed 8 years ago.
I've done some research over internet and i cannot find the right answer that closes to my problem. I'm just beginner in php and I don't understand advance programming yet. My problem is I want to get the current date in next month.
suppose:
today is Feb 15 2014,
I want to get date
March 15 2014,
April 15 2014,
May 15 2014,
June 15 2014,
July 15 2014,
August 15 2014,
September 15 2014,
October 15 2014,
November 15 2014,
December 15 2014,
January 15 2015, and so on and so fourth.
$new_date = date('F d Y', strtotime('+1 month'));
or
for ($i = 1; $i <12; $i++){
$new_date = date('F d Y', strtotime("+$i month"));
echo $new_date;
}
Here is another solution:
$begin = new DateTime( '2014-03-15' );
$end = new DateTime( '2015-01-31' );
$interval = new DateInterval('P1M');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date){
echo $date->format("F d Y") . "<br>";
}
or this if you want to do it without a end date:
$date= new DateTime( '2014-03-15' );
for($i = 1; $i < 10; $i++) {
$date = $date->modify( '+1 month' );
echo $date->format("F d Y") . "<br>";
}
Related
This question already has answers here:
Get the last 12 months in PHP
(5 answers)
Closed 3 years ago.
I'm trying to use a loop to show the last 12 months, but March appears twice.
for ($i=0; $i < 12; $i++) {
$month = date("d/m/Y", strtotime("now -$i month"));
echo "$month<br>";
}
Output:
30/01/2020
30/12/2019
30/11/2019
30/10/2019
30/09/2019
30/08/2019
30/07/2019
30/06/2019
30/05/2019
30/04/2019
30/03/2019
02/03/2019
How can I solve this?
Use the first day of the month as the basis in your script.
"first day of this month -$i month"
Use DateTime and keep track of month/year combinations that you already had:
$dt = new DateTime();
$previous = [];
for ($i=0; $i < 12; $i++) {
$month = $dt->format("d/m/Y");
echo "$month<br>".PHP_EOL;
$previous[$dt->format('Y-m')] = true;
$dt->modify('-1 month');
while (array_key_exists($dt->format('Y-m'), $previous)) {
$dt->modify('-1 day');
}
}
If this encounters a previously encountered month-year combination, it starts substracting days until it reaches the previous month.
Will produce this output:
30/01/2020
30/12/2019
30/11/2019
30/10/2019
30/09/2019
30/08/2019
30/07/2019
30/06/2019
30/05/2019
30/04/2019
30/03/2019
28/02/2019
You probably want to use DatePeriod for this task and not date. It's much simpler and more sane.
$start = new DateTime;
$start->setDate($start->format('Y'), $start->format('n'), 1); // Normalize the day to 1
$start->sub(new DateInterval('P12M'));
$interval = new DateInterval('P1M');
$recurrences = 12;
foreach (new DatePeriod($start, $interval, $recurrences, true) as $date) {
echo $date->format('F, Y'), "\n"; // attempting to make it more clear to read here
}
Output:
February, 2019
March, 2019
April, 2019
May, 2019
June, 2019
July, 2019
August, 2019
September, 2019
October, 2019
November, 2019
December, 2019
January, 2020
I'm working with some dates in PHP, and the problem is that today, php return me that we are the 1st of April.
I don't really know why
Tried to change the code to get the date.
$actArray= array();
for($i=0;$i<30;$i++){
$date = new DateTime(date("Y-m-d"));
$date->modify("-".$i." days");
$date->modify("-1 months");
$actArray[date("Y-m-d",time()-60*60*24*$i)]=array("display"=>$date->format("Y, m, d"),"MaxPlayers"=>0,"PlayersOn"=>0,"Register"=>0);
}
Alerdy tried
for($i=0;$i<30;$i++){
$date = new DateTime(date("Y-m-d",time()-60*60*24*$i));
$date->sub(new DateInterval("P1M"));
$actArray[date("Y-m-d",time()-60*60*24*$i)]=array("display"=>$date->format("Y, m, d"),"MaxPlayers"=>0,"PlayersOn"=>0,"Register"=>0);
}
Same result
It seem that he skip 3 days.
Output : 2019, 03, 01 2019, 02, 28 2019, 02, 27 2019, 02, 26 2019, 02, 25 2019.....2019, 02, 28
Thanks for you help
Why don't you use date() function? It returns the local time/date.
you can get today's date:
echo date("Y, M, d");
for more details: date function php
https://www.guru99.com/php-date-functions.html good reference
Not every month has 30 days, some have even less.
Not all days have 24 hours.
DateTime / strtotime has so many options, you'll never need to do fancy time calculations yourself.
Consider this code:
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
$today->sub(DateInterval::createFromDateString('30 days'));
echo $today->format('Y-m-d') . PHP_EOL;
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
$today->sub(DateInterval::createFromDateString('1 month'));
echo $today->format('Y-m-d') . PHP_EOL;
Output:
2019-03-29
2019-02-27
2019-03-29
2019-03-01
You see, there is a difference between "30 days" and "1 month"...
Another example:
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
for($i = 0; $i < 5; $i ++) {
$today->add(DateInterval::createFromDateString('1 days'));
echo $today->format('Y-m-d') . PHP_EOL;
}
2019-03-29
2019-03-30
2019-03-31
2019-04-01
2019-04-02
2019-04-03
How can I loop the year and months with some given dates?
Below is my current code and I can't get it running
$Startdate = '2017-01';
$Enddate = '2018-06';
for($selectedDate = date("Y-m",$begin); $selectedDate <= date("Y-m",$end); $selectedDate++){
$resultY = date("Y",strtotime($selectedDate));
$resultM = date("m",strtotime($selectedDate));
echo $resultY;
$echo resulthM;
}
The output should be:
2017 1
2017 2
2017 3
2017 4
2017 5
2017 6
2017 7
2017 8
2017 9
2017 10
2017 11
2017 12
2018 1
2018 2
2018 3
2018 4
2018 5
2018 6
If I were you :) I will try with DateTime class to generate months between your $Startdate and $Enddate. See DateTime
<?php
$start = new DateTime('2017-01');
$end = new DateTime('2018-06');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . PHP_EOL;
}
DEMO: https://3v4l.org/FvmS4
Since you were familiar with strtotime, you can amend your code to the following to execute the desired results.
$begin = date("Y-m", strtotime("2017-01")); // Replace this with date to begin.
$end = date("Y-m"); // Replace this with date to end.
for($selectedDate = date("Y-m", strtotime($begin)); $selectedDate <= date("Y-m", strtotime($end)); $selectedDate = date("Y-m", strtotime($selectedDate . "+1 Month"))){
$resultY = date("Y", strtotime($selectedDate));
$resultM = date("m", strtotime($selectedDate));
echo $resultY;
echo $resultM;
}
However, equally, user don't angry me, has an answer that will allow you to use the DateTime objects and manipulate them instead, so if you'd rather switch over your code to something potentially more reliable, you could do that also.
$startDate = new \DateTime('2017-01-01');
$endDate = new \DateTime('2018-06-01');
for($selectedDate = $startDate; $selectedDate <= $endDate; $selectedDate->modify('+1 month')) {
// format $selectedDate;
$resultY = $selectedDate->format('Y');
$resultM = $selectedDate->format('m');
// print content
echo $resultY;
echo "\t"; // print tab
echo $resultM;
echo "\n"; // print new line
}
You can use DateTime::modify and walk the months forward
$Startdate = '2017-01';
$Enddate = '2018-06';
$DateTime = new DateTime($Startdate.'-01');
echo $DateTime->format('Y')."\t".$DateTime->format('n')."\n";
do{
$DateTime->modify('+1 months');
echo $DateTime->format('Y')."\t".$DateTime->format('n')."\n";
if($DateTime->format('Y-m') == $Enddate) break;
}while(true);
Just make sure the Enddate is a valid Year/Month and happens after Startdate or in this example you'll loop forever.
There are probably other ways to do the loop that avoids that.
But I didn't see DateTime::modify used in an answer so I thought I would throw one together.
Output:
2017 1
2017 2
2017 3
2017 4
2017 5
2017 6
2017 7
2017 8
2017 9
2017 10
2017 11
2017 12
2018 1
2018 2
2018 3
2018 4
2018 5
2018 6
Sandbox
I usually use this method when I want to make a select/option for stuff like months. But I use this format str_pad($DateTime->format('n'),2,' ',STR_PAD_LEFT).' - '.$DateTime->format('F') OR ' 2 - February', notice the space on the left ... :) ... that way they all line up nice and neat like.
Anyway, cheers!
I am displaying month titles 3 month into the future as well as getting the 1st and last day of each of those months.
for($i = 1; $i < 4; $i++) { // For each month for 3 months
$monthTitle = date('F Y', strtotime('+'.$i.' month'));
$begin_date = date('Y-m-01', strtotime('+'.$i.' month')); // First day of calendar month in future.
$end_date = date('Y-m-t', strtotime('+'.$i.' month')); // Last day of calendar months in future.
};
Nov. 29, 2015 output is:
December 2015
2015-12-01
2015-12-31
January 2016
2016-01-01
2016-01-31
February 2016
2016-02-01
2016-02-29
This was working great right up until yesterday, Nov. 29, 2015 but today Nov. 30, 2015 it skips February.
Nov. 30, 2015 output is:
December 2015
2015-12-01
2015-12-31
January 2016
2016-01-01
2016-01-31
March 2016
2016-03-01
2016-03-31
I'm guessing a bug but does anybody know of a work around?
Thanks to #devlin carnate for pointing me in the right direction.
for($i = 1; $i < 4; $i++) { # for each month
$tmp = date('Y-m-15'); // Get the middle of the month to avoid PHP date bug.
$begin_date = date('Y-m-01', strtotime($tmp . '+'.$i.' month')); // First day of calendar month in future.
$end_date = date('Y-m-t', strtotime($begin_date)); // Last day of calendar months in future.
$monthTitle = date('F Y', strtotime($begin_date));
};
This seems to work very well.
You can use DateInterval to add one month to the current date, so you can get the first and the last day of month.
<?php
$date = new DateTime('2015-12-01');
$i = 0;
while($i < 3){
printf("%s | first day: %s, | last day: %s <br>", $date->format('F Y'), $date->format('d'), $date->format('t'));
$date->add(new DateInterval('P1M'));
$i++;
}
Output:
December 2015 - first day: 01, | last day: 31
January 2016 - first day: 01, | last day: 31
February 2016 - first day: 01, | last day: 29
if last day of next month is needed then you can use this
$d = new DateTime( '2010-01-31' );
$d->modify( 'last day of next month' );
echo $d->format( 'Y-m-d' ), "\n";
I have the following to loop through each month of the year. However, it seems to skip February.
$start = new DateTime('2015-01-01');
$start->modify('last day of this month');
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$timestamps = array();
foreach ($period as $dt) {
$dt->modify('last day of this month');
echo 'C:' . $current->format('d F Y') . '<br>';
echo 'S:' . $start->format('d F Y') . '<br>';
echo 'D:' . $dt->format('d F Y') . '<br>';
echo '<br><br>';
}
However, the above outputs:
C:17 March 2015
S:31 January 2015
D:31 January 2015
C: 17 March 2015
S:31 January 2015
D:31 March 2015
C: 17 March 2015
S:31 January 2015
D:30 April 2015
Can anyone spot my mistake? I expected the second D to have a value of the 28 February 2015.
I just want a list of months that have already been passed.
Update
The problem highlighted by MLeFevre in the comments is that working with date intervals can be tricky. See Example #3 Beware when adding months http://php.net/manual/en/datetime.add.php.
Rather than use a DatePeriod, why not just use the modify method slightly differently like this:
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
while($current < $end) {
$current->modify('last day of next month');
echo 'C:' . $current->format('d F Y') . '<br>';
}
In your question, you're firstly adding a month, then going to the end of that month. This doesn't work, as the length of each month varies.
Sample output:
C:30 April 2015
C:31 May 2015
C:30 June 2015
C:31 July 2015
C:31 August 2015
C:30 September 2015
C:31 October 2015
C:30 November 2015
C:31 December 2015
C:31 January 2016
C:29 February 2016
C:31 March 2016
// etc.
To loop from $start to $current, you could change the logic slightly like this:
$start = new DateTime('2015-01-31'); // start from end of month
$current = new DateTime('now');
do {
echo 'C:' . $start->format('d F Y') . '<br>';
} while($start->modify('last day of next month') < $current);
Output:
C:31 January 2015
C:28 February 2015
It happen because February has 28 days and your interval is 1 month (30 days). So it skips 30 days from 30 January to 2 March. Then it move to last day of March.
Change
$start->modify('last day of this month');
to
$start->modify('first day of this month');
Your first date is 31-Jan-2015. Since February has no 31st, it's going to March 3rd. Then you are telling it to go to the end of that month which is why you are getting the end of March after January and not February.