PHP get dates between two dates not working as expected - php

I am trying to get all dates between two dates using DatePeriod class. Its working fine when the dates inputed are of the same month, but not returning all dates when the two dates are of different months.
If the dates are say 2013-06-27 and 2013-07-05 its only returning 2013-06-27, 2013-06-28, 2013-06-29, 2013-06-30. Its not giving the rest of the dates.
CODE
$begin = new DateTime($start);
$last = new DateTime($end);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $last);

I cannot reproduce the behavior
<?php
$start = '2013-06-27';
$end = '2013-07-05';
$begin = new DateTime($start);
$last = new DateTime($end);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $last, DatePeriod::EXCLUDE_START_DATE);
echo 'phpversion: ', phpversion(), "\n";
foreach ( $period as $dt ) {
echo $dt->format("l Y-m-d H:i:s"), "\n";
}
echo "done.\n";
prints
phpversion: 5.4.7
Friday 2013-06-28 00:00:00
Saturday 2013-06-29 00:00:00
Sunday 2013-06-30 00:00:00
Monday 2013-07-01 00:00:00
Tuesday 2013-07-02 00:00:00
Wednesday 2013-07-03 00:00:00
Thursday 2013-07-04 00:00:00
done.
Which version of php do you use?

Related

get time intervals with time range

I am trying to get time interval with custom start and end time variables for which i have searched and find its relevant information on this link.
I have tried the following code but its giving errorUncaught Error: Call to a member function date() on string
$start = date("H:i",strtotime('08:30 AM'));
$end = date("H:i",strtotime('06:00 PM'));
for($i = $start; $i <= $end; $i->modify(' +30 MINUTE')){
echo $i->date("H:i");
}
You need to use the builtin \DateTime class and the \DateInterval class as well
$begin = new DateTime('08:30:00');
$end = new DateTime('12:45:00');
$interval = DateInterval::createFromDateString('30 minute');
$period = new DatePeriod($begin, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("H:i\n");
}
RESULTS
08:30
09:00
09:30
10:00
10:30
11:00
11:30
12:00
12:30
And if the time roles over to another day something like this
$begin = new DateTimeImmutable('2022-03-01 16:00:00');
$end = (new DateTime())->createFromImmutable($begin)->add(new DateInterval('P1D'))->settime(8,30,0);
$interval = DateInterval::createFromDateString('30 minute');
$period = new DatePeriod($begin, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("d/m/Y H:i\n");
}

Date Period PHP

I want to render dates period base on start date and end date, for example:
Input:
Start date: 30/12/2017
End date: 31/03/2017
Interval: every month
Output I want:
30/12/2017
30/01/2018
30/03/2018 (February is missing because it not have 30th)
There my code:
function period_days($start_date, $int, $end_date){
$begin = new DateTime( $start_date );
$end = new DateTime( $end_date );
$interval = DateInterval::createFromDateString($int);
$period = new DatePeriod($begin, $interval, $end->modify( '+1 day' ));
return $period;
}
echo period_days('30-12-2017', '1 month', '31-03-2018');
Result return wrong (3rd should be "2018-03-30"):
"2017-12-30 00:00:00"
"2018-01-30 00:00:00"
"2018-03-02 00:00:00"
Edit: Explain about Input:
Start date format can be '31/12/2017' or 'first Monday of January 2018' or 'third Tuesday of December 2017' or '28 December 2017' ...
Interval can be '1 day', '1 month', '2 months', '1 year' ...
End date format is d-m-Y '01/12/2018'
I use this function to add schedule recurring event, something like plugin The Event Calendar, you guys can see example on https://wpshindig.com/events/community/add
I could suggest you a work around.
Since DatePeriod breaks for February, we could get Year and month and append date separately. But this will only be working for one year.
Example :
function periodDays($start_date, $int, $end_date){
$begin = new DateTime($start_date);
$end = new DateTime($end_date);
$startDay = $begin->format("d");
$interval = DateInterval::createFromDateString($int);
$period = new DatePeriod($begin, $interval, $end);
foreach($period as $date){
echo $date->format("Y-m-") .$startDay. "<br>";
}
}

How to include the end date in a DatePeriod?

I am trying to get a Date range for all workdays this week. I have written the following code to do so.
Code
$begin = new DateTime('monday this week'); 2016-07-04
$end = clone $begin;
$end->modify('next friday'); // 2016-07-08
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval, $end);
foreach($daterange as $date) {
echo $date->format('Y-m-d')."<br />";
}
Output
2016-07-04
2016-07-05
2016-07-06
2016-07-07
In the output friday is missing. I can fix this by doing $end->modify('next saturday') but I was wondering why the last day of a DatePeriod is not included in the range.
The iterator seems to check the time as well as the date, it excludes the end element if the time in the endDate is less that or equal to the time in the start date.
So ensure the time of the end date is at least a second greater that that of the start date.
// this will default to a time of 00:00:00
$begin = new DateTime('monday this week'); //2016-07-04
$end = clone $begin;
// this will default to a time of 00:00:00
$end->modify('next friday'); // 2016-07-08
$end->setTime(0,0,1); // new line
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval, $end);
foreach($daterange as $date) {
echo $date->format('Y-m-d')."<br />";
}
Try this code
<?php
$begin = new DateTime('2016-07-04');
$end = clone $begin;
$end->modify('next friday'); // 2016-07-08
$end->modify('+1 day');
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval, $end);
foreach ($daterange as $date) {
echo $date->format('Y-m-d') . PHP_EOL;
}
In PHP 8.2 you can use DatePeriod::INCLUDE_END_DATE as constructor option!
https://www.php.net/manual/en/class.dateperiod.php#dateperiod.constants.include-end-date

List all the years between dates

I am looking to list every year between dates using PHP and Mysql data base, the code is this:
<?php
$start = new DateTime('2010-12-02');
$start->modify('first day of this month');
$end = new DateTime('2016-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 year');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y") . "<br>\n";
}
?>
Output
2010
2011
2012
2013
2014
2015
Missing the year 2016.
How I can do to make 2016 also returns? It should return as it does to 2010
$start = '2010-12-02';
$end = '2016-05-06';
$getRangeYear = range(gmdate('Y', strtotime($start)), gmdate('Y', strtotime($end)));
print_r($getRangeYear);
use the range function to get list of ranging numbers, first parameter start range, and second ending range..
http://php.net/manual/en/function.range.php
It is simple: you are iterating between 2010-12-02 and 2016-05-06. The generated dates are:
2010-12-02 -> ok
2011-12-02 -> ok
2012-12-02 -> ok
2013-12-02 -> ok
2014-12-02 -> ok
2015-12-02 -> ok
2016-12-02 -> over 2016-05-06 - stop algorithm.
I do not know exactly what do you want to do, but it seem that you should change end date.
<?php
$start = new DateTime('2010-12-02')->modify('+1 year');
$start->modify('first day of this month');
$end = new DateTime('2016-05-06');
$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 year');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y") . "<br>\n";
}
?>

How to get a DatePeriod with "every first thursday in month"?

I'm having two DateTime-objects:
$start = new DateTime('first thursday of June 2012');
$end = new DateTime('2012-12-31');
I need a DatePeriod that contains all first Thursdays of the months between this two dates. When using
$interval = new DateInterval('P1M');
$period = new DatePeriod($start, $interval, $end);
This only adds 1 month without respecting the condition "first thursday".
Also something like this does not work:
$interval = DateInterval::createFromDateString('1 month first thursday');
$period = new DatePeriod($start, $interval, $end);
Does anyone know how I can achieve this?
I've struggled with this the last two hours - as soon as I posted it here I got the solution.
I only had to change the DateInterval string to "first thursday of next month".
$start = new DateTime('first thursday of June 2012');
$end = new DateTime('2012-12-31');
$interval = DateInterval::createFromDateString('first thursday of next month');
$period = new DatePeriod($start, $interval, $end);
Works! DateTime rocks ;-)

Categories