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

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 ;-)

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");
}

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";
}
?>

Add datetime Value

I'm searching for the best way to echo day numbers in a week.
First i need to check what week there is.
And then echo all dates of the week into variables.
This is what i got:
//This Week Variable dates
$this_year = date('Y');
$this_week_no = date('W');
$this_week_mon = new DateTime();
$this_week_mon->setISODate($this_year,$this_week_no);
How do i rise tue by one day?
$this_week_tue = $this_week_mon ++;
You can use DateTime::modify():
$this_week_mon->modify('+1 day');
or DateTime::add() which accepts a DateInterval() object:
$this_week_mon->add(new DateInterval('P1D'));
You can loop through all of the days of the week using DatePeriod():
$start = new DateTime();
$start->setISODate($this_year,$this_week_no);
$end = clone $start;
$end->modify('+1 week');
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('N');
}
$this_week_mon->modify('+1 day');
Should increment $this_week_mon by one day. To increase by more, just use days;
$this_week_mon->modify('+27 day');
Would increment by 27 days.

PHP get dates between two dates not working as expected

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?

Categories