I am trying to get the date of every monday skipping a month each time but I keep getting only the monday of the first week. This is my code:
$begin = new \DateTime("2017-04-01");
$end = new \DateTime("2017-08-31");
$interval = \DateInterval::createFromDateString("next monday of +2 months");
$period = new \DatePeriod($begin, $interval, $end);
foreach ( $period as $dt )
{
// echo the date for each monday found in the second month
}
Any help would be greatly appreciated.
You seem to have mixed the $begin and $end values. Also, the DateInterval will only have one Monday every single month. I was not able to find a interval expression to get every Monday in every other month, so I did the filtering manually. In this example we use the month from the begin date, and includes the Mondays from that date, skip two months and so on.
<?php
$end = new \DateTime("2017-04-01");
$begin = new \DateTime("2007-08-31");
$month_even = ((int) $begin->format('m')) % 2 === 0;
$interval = \DateInterval::createFromDateString("next monday");
$period = new \DatePeriod($begin, $interval, $end);
foreach ($period as $dt) {
// Check if we want to show even months, make sure that the current month is even
// or, if we want to show odd months, the month should be odd.
if ((((int) $dt->format('m')) % 2 === 0) === $month_even) {
echo $dt->format('d-m-Y') . PHP_EOL;
}
}
Outputs:
31-08-2007
01-10-2007
[...]
06-02-2017
13-02-2017
20-02-2017
27-02-2017
Related
Example: $startDate is Sunday 2021-06-20 and $endDate is Wednesday 2021-07-07. Then I want it to list:
Monday 2021-06-21
Monday 2021-06-28
But not Monday 2021-07-05 because the whole(monday thru sunday) week is not within the range. I figured I need the find the last Sunday within the range and use that date as the endDate.
One possible approach:
function isMonday($date) {
return $date->format('N') === '1';
}
function isSunday($date) {
return $date->format('N') === '7';
}
function getMondays($start, $end) {
$mondays = [];
$datePeriod = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach ($datePeriod as $date) {
if (isMonday($date)) $mondays[] = $date;
}
if (!isSunday($end)) array_pop($mondays);
return $mondays;
}
$startDate = new DateTime('2021-06-20');
$endDate = new DateTime('2021-07-07');
var_dump(getMondays($startDate, $endDate));
3v4l Demo. It's rather direct: there's a DatePeriod Traversable object created from $start and $end dates with 1 day interval, that is iterated with foreach; each date that's a Monday is stored in an array. Last step is discarding the very last item of that array if the endDate is not Sunday.
How to check if month exist in specific period ($date1 and $date2)
$month = '2016-01';
$date1 = '2016-01-05';
$date2 = '2016-02-04;
First convert the month into a date, like the first day of the month. Then you can compare the dates to check if the month lies in between:
$month_day = date ('Y-m-01', strtotime($month) );
$date1_day = date ('Y-m-01', strtotime($date1) );
$date2_day = date ('Y-m-01', strtotime($date2) );
if ( ($month_day >= min($date1_day, $date2_day))
&& ($month_day <= max($date1_day, $date2_day)) )
{ }
I got a best answer for my question on his link The Answer
This answer get months between two dates
$start = (new DateTime('2016-01-05'))->modify('first day of this month');
$end = (new DateTime('2016-02-04'))->modify('first day of this month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$monthsArray = [];
foreach ($period as $dt) {
$monthsArray[] = $dt->format("Y-m"); // I put months exist in this period on array to check later if the $month exist on this array or not
}
You could search the strings using strpos(). http://php.net/manual/en/function.strpos.php
ex:
if (strpos($date1,$month) || strpos($date2,$month)){/* do stuff */}
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.
I have found a problem with using DatePeriod which might be because I am stupid lol.
As you can see I have added +1 to my end date because I want to include the last date of the range.
But my issue is when I have ending date 31 it makes it to 32 which is not a date so it throws out an error.
Is there a way to include the ending date or to make the +1 work?
$period = new DatePeriod(
new DateTime($event['startyear'].$event['startmonth'].$event['startdate']),
new DateInterval('P1D'),
new DateTime($event['endyear'].$event['endmonth'].$event['enddate'] +1)
);
foreach ($period as $savedDate) {
echo $savedDate;
}
You should create the date object for the initial date (without the +1) and then increment the day of that object by 1 day.
For example:
$date1 = new DateTime($event['endyear'].$event['endmonth'].$event['enddate']);
$date2 = new DateTime($event['endyear'].$event['endmonth'].$event['enddate']);
$date2->modify('+1 day');
$period = new DatePeriod($date1, new DateInterval('P1D'), $date2);
What about this:
$endDate = mktime(0,0,0, $event['endmonth'], $event['enddate'], $event['endyear']);
$counter = 0;
while($endDate >= $date = mktime(0,0,0, $event['startmonth'], $event['startdate']+$counter++, $event['startyear']) ) {
echo date('Y/m/d', $date);
}
Say you're given two Unix Timestamps like this:
$startDate = 1330581600;
$endDate = 1333170000;
I want to loop through each day in that range and output it something like this:
Start Loop
Day Time Stamp: [Timestamp for the day within that loop]
End Loop
I've tried looking for some type of function to do this, but i'm not sure if it's even possible.
As I love DateTime, DateInterval and DatePeriod, here is my solution:
$start = new DateTime();
$end = new DateTime();
$start->setTimestamp(1330581600);
$end->setTimestamp(1333170000);
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach($period as $dt) {
echo $dt->format('Y-m-d');
echo PHP_EOL;
}
This seems to be confusing at first, but it's a very logical approach.
With DatePeriod you are defining a start and an end of a period with an interval of 1 day (look up the format at DateInterval), and then you can just iterate over it.
Finally, in every iteration you get back a DateTime object on which you can use DateTime::format()
for ($t = $start; $t < $end; $t = strtotime('+1 day', $t)) {
...
}