PHP date "last weekday" outputting the wrong month - php

I'm trying to get the last weekday of the current month using the code below.
I was expecting this to behave just like all of the other operators like last friday of and output the last weekday of this month. but instead its outputting the last weekday of the previous month.
I know that I can rectify this by using modify( '+1 month' ) but why? Why is it the other operators like last tuesday of work fine but last weekday needs to be bosted by 1 month?
<?php
// outputs the previous months date
$gettoday = date( "Y-m-01" );
$freqdate = date( 'Y-m-d', strtotime( 'last weekday '.$gettoday ) );
echo 'next '.$freqdate;
//get the correct date
$gettoday = new DateTime( $gettoday );
$gettoday->modify( '+1 month' );
$gettoday = date_format( $gettoday, 'Y-m-01' );
$freqdate = date( 'Y-m-d', strtotime( $gettoday . ' last weekday' ) );
echo 'next '.$freqdate;
?>

It appears you had a wrong understanding of what “last” actually means here.
That has nothing to do with the last day or week of the month - it is “last” as in “the closest previous one”.
You can start with something like strtotime('last day of 2020-03') - that would give you 31 Mar 2020, which is a Tuesday.
If you then check what day of the week this is, and it would be either a Saturday or a Sunday - then you can go last friday on that value again, to land on the latest week day of the month.
Edit:
Example for all months of 2020
for($i=1; $i<13; ++$i) {
$year_month = '2020-'.$i;
$last_of_month = strtotime('last day of '.$year_month);
$weekday = date('N', $last_of_month);
if($weekday < 6) {
echo 'last weekday of ', $year_month, ' is ', date('Y-m-d, l', $last_of_month), "<br>\n";
}
else {
$last_weekday_of_month = strtotime('last friday', $last_of_month);
echo 'last day of ', $year_month, ' is ', date('Y-m-d, l', $last_of_month), ' - last weekday of ', $year_month, ' is ', date('Y-m-d, l', $last_weekday_of_month), "<br>\n";
}
}
This will get you the following output:
last weekday of 2020-1 is 2020-01-31, Friday
last day of 2020-2 is 2020-02-29, Saturday - last weekday of 2020-2 is 2020-02-28, Friday
last weekday of 2020-3 is 2020-03-31, Tuesday
last weekday of 2020-4 is 2020-04-30, Thursday
last day of 2020-5 is 2020-05-31, Sunday - last weekday of 2020-5 is 2020-05-29, Friday
last weekday of 2020-6 is 2020-06-30, Tuesday
last weekday of 2020-7 is 2020-07-31, Friday
last weekday of 2020-8 is 2020-08-31, Monday
last weekday of 2020-9 is 2020-09-30, Wednesday
last day of 2020-10 is 2020-10-31, Saturday - last weekday of 2020-10 is 2020-10-30, Friday
last weekday of 2020-11 is 2020-11-30, Monday
last weekday of 2020-12 is 2020-12-31, Thursday

Related

Get last day of last week using datetime

I have tried the following code to get the last day of week in the next month:
$paymentMonth = "2017-07";
$wee = new \DateTime($paymentMonth);
$firstDate = clone $wee->modify(('Sunday' == $wee->format('l')) ? 'Monday last week' : 'Monday this week'); //Monday of last week of previous month
$lastDate = clone $wee->modify('+1 month')->modify(('Sunday' == $wee->format('l')) ? 'Sunday last week' : 'Sunday this week');
/**^^^^
* This works in most cases of months
* but for july 2017, I want the last day of the first week of next month.
*/
echo $firstDate->format('Y-m-d'); //Gives 26-june
echo $lastDate->format('Y-m-d'); //Gives 30-july in this case i want the 31 of july...
What is the cleanest way to get the last day of first week of next month using DateTime
Use format placeholder 'w' to obtain day of week of first of the month. Then subtract the relative number of the day you want to obtain (Sunday = 7, Saturday = 6, Friday = 5 and so on). If you want to obtain first Sunday of the month:
$paymentMonth = '2017-06-01';
$d = new DateTime($paymentMonth);
$w = $d->modify('+1 month')->format('w'); // * Returns 6 as 1st July 2017 is Saturday
$sun = (7-$w + 1)%7; // * First Sunday is 7-$w + 1 = 2
$lastDate = new DateTime($d->format('Y-m') . "-$sun");
Module %7 is required as on Sunday format('w') returns 0.
Don't rely on format('l') as result is environment dependent.
I found the solution, was pretty easy actualy :
$paymentMonth = '2017-07';
$fweek = new \DateTime($paymentMonth);
$firstDate = $fweek->modify(('Sunday' == $fweek->format('l')) ? 'Monday last week' : 'Monday this week'); //Monday of last week of previous month
$lweek = new \DateTime($paymentMonth);
$lastDate = $lweek->modify('+1 month')->modify(('Sunday' == $lweek->format('l')) ? 'Sunday last week' : 'Sunday this week'); //Sunday of first week of next month
echo $firstDate->format('Y-m-d') . ' - ' . $lastDate->format('Y-m-d');

Finding the date for 29th last month, two months ago, etc

I'm looking to find the date of the 29th of this month, the 29th of next month, the 29th of last month and so on...
I know you can use this kind of code to find days of the week:
$friday_last = date("d/m/Y", strtotime("last Friday"));
$friday_due = date("d/m/Y", strtotime("this Friday"));
Is there a similar way to find a certain day (29th) of each month or would I have to use a different code?
You need to use DateTime() as it makes working with dates much easier. You'll notice I start by going to the first day of each month. That's so this doesn't break when you get to the 29th-30th of each month as weird date things start to happen.
echo (new DateTime())->modify('first day of this month')->format("29/m/Y");
echo (new DateTime())->modify('first day of previous month')->format("29/m/Y");
echo (new DateTime())->modify('first day of next month')->format("29/m/Y");
Demo
echo (new DateTime())->modify('first day of this month')->modify('-2 months')->format("29/m/Y");
Demo
Using date() with strtotime() will gives you 29th from each month within this year:
<?php
for ($i = 1; $i <= 12; $i++) {
$d = "2016-" . $i . "-29";
echo "29th of Month $i is: " . date("l", strtotime($d)) . '<br>';
}
?>
Output:
29th of Month 1 is: Friday
29th of Month 2 is: Monday
29th of Month 3 is: Tuesday
29th of Month 4 is: Friday
29th of Month 5 is: Sunday
29th of Month 6 is: Wednesday
29th of Month 7 is: Friday
29th of Month 8 is: Monday
29th of Month 9 is: Thursday
29th of Month 10 is: Saturday
29th of Month 11 is: Tuesday
29th of Month 12 is: Thursday
To create an array with current and next 11 months 29th day (for previous months replace +1 month with -1 month. In this example I use +1 to explain february issue, that is not present in past february):
$baseDate = date_create()->modify( 'first day of this month' );
$dates = array();
for( $i = 0; $i<12; $i++ )
{
$newDate = clone $baseDate;
$dates[] = $newDate->modify( '+28 days' );
$baseDate->modify( '+1 month' );
}
The problem — as you can imagine — is with february:
foreach( $dates as $date )
{
echo $date->format( 'Y-m-d' ).PHP_EOL;
}
Will output:
2016-05-29
2016-06-29
2016-07-29
2016-08-29
2016-09-29
2016-10-29
2016-11-29
2016-12-29
2017-01-29
2017-03-01 <-----
2017-03-29
2017-04-29
If you want a result like “29th month's day OR last month's day” modify above for loop in this way:
for( $i = 0; $i<12; $i++ )
{
$newDate = clone $baseDate;
if( $newDate->modify( '+28 days' )->format( 'm' ) != $baseDate->format( 'm' ) )
{
$newDate->modify( 'last day of previous month' );
}
$dates[] = $newDate;
$baseDate->modify( '+1 month' );
}
Result:
2016-05-29
2016-06-29
2016-07-29
2016-08-29
2016-09-29
2016-10-29
2016-11-29
2016-12-29
2017-01-29
2017-02-28 <-----
2017-03-29
2017-04-29
I'm not sure when this started, but now you can do so by using just date() and strtotime(), like this:
$d = date("Y-m-d 00:00:00", strtotime('first day of 2 months ago'));
$l = date("Y-m-d 00:00:00", strtotime('last day of 2 months ago'));
print_r($d);
print_r($l);
Assuming today (2023-02-01) The above will display:
2022-12-01 00:00:00
2022-12-31 00:00:00
Sample:
https://onlinephp.io/c/db73f

PHP: how to get a day in last week?

Is there an easy way to get last week's, say, Monday? If today is Tuesday, I do not want yesterday's Monday. Rather, I want the Monday 8 days ago (last week's Monday). Then I want that Monday's proceeding Sunday. Basically, I'm trying to get the date range for last week, Monday to Sunday.
This doesn't always work right:
date('Y-m-d', strtotime('last Monday')
Suggestions?
You can use “this week” format:
$monday = strtotime( 'this week', strtotime( '7 days ago' ) );
$sunday = strtotime( '+ 6 days', $monday );
3v4l.org demo
“this_week” returns monday of previous week, then — adding 6 days — you obtain the monday of relative week.
The strtotime function accepts the current date as a parameter.
http://php.net/manual/en/function.strtotime.php
Just pass in strtotime('last Sunday') as the parameter to get a weekday of the last full week.
$beginning_of_week = strtotime('last Sunday');
$result = date('Y-m-d', strtotime('last Monday', $beginning_of_week));
echo $result;

start and end of the week by given date

Is there a short preset function to find the start (Monday) and end (Sunday) of the week by a given $date ?
I tried:
1)
date("Y-m-d", strtotime('sunday this week ' . $date));
date("Y-m-d", strtotime('monday this week ' . $date));
But this fails when $date is Sunday... it returns the Monday of Next week.
2) also this
date("Y-m-d", strtotime('last monday ' . $date));
date("Y-m-d", strtotime('next sunday ' . $date));
But again if $date is Monday or Sunday it gives the previous/next week.
I know it can be done with few condition .. but I m look for more out of the box solution.
You can use DateTime::format('N') to get the ISO-8601 day of the week (1 = Monday .. 7 = Sunday) and do some simple date arithmetic to get the Monday and the Sunday of the week that contains the specified date (I assume you want the week starting on Monday).
// Today (or any other day you like)
$today = new DateTime('now');
echo('Today: '.$today->format('Y-m-d (D)')."\n");
// Day of week (1 = Monday .. 7 = Sunday)
$dow = $today->format('N');
// Monday is ($dow-1) days in the past
$monday = clone $today;
$monday->sub(new DateInterval('P'.($dow-1).'D'));
echo('Monday: '.$monday->format('Y-m-d')."\n");
// Sunday is 6 days after Monday
$sunday = clone $monday;
$sunday->add(new DateInterval('P6D'));
echo('Sunday: '.$sunday->format('Y-m-d')."\n");

First Date of Each Week in a Month

I am having a small issue where I have the month (December 2013) and the Week Number (1, 2, 3 etc) and I need to find out the first date of each week.
I cannot do a simple search like finding the closest Sunday relative to a date since some weeks don't start on a Sunday at all.
Any help would be appreciated.
Considering you have the date of 1st of any month :
First find the next Sunday
Then add 1 week at a time to it to get subsequent Sunday's
Code :
$firstDayOfMonth = '2013-12-01'; // Try also with first day of other months
$week1 = $firstDayOfMonth;
$week2 = date( "Y-m-d" ,strtotime('next Sunday', strtotime( $week1 ) ) );
$week3 = date( "Y-m-d" ,strtotime('+1 week', strtotime( $week2 ) ) );
$week4 = date( "Y-m-d" ,strtotime('+1 week', strtotime( $week3 ) ) );
$week5 = date( "Y-m-d" ,strtotime('+1 week', strtotime( $week4 ) ) );
echo '
Week 1 starts on : ' .$week1 .'<br>
Week 2 starts on : ' .$week2 .'<br>
Week 3 starts on : ' .$week3 .'<br>
Week 4 starts on : ' .$week4 .'<br>
Week 5 starts on : ' .$week5 .'<br>';
Output :
Week 1 starts on : 2013-12-01
Week 2 starts on : 2013-12-08
Week 3 starts on : 2013-12-15
Week 4 starts on : 2013-12-22
Week 5 starts on : 2013-12-29
Just try
<?php
$first_day_this_month = date('M-D-Y',strtotime(date('M-01-Y')));
echo date('M-D-Y',strtotime(date('M-01-Y')))." = ".date('M-d-Y',strtotime(date('M-01-Y')));//First day of month
echo "<br>";
$last_day_this_month = date('t');//last day of month
$last_day_num=intval($last_day_this_month);
for($i=1;$i<$last_day_num;$i++)
{
$first_day_this_month = date('M-D-Y',strtotime(date('M-'.$i.'-Y')));//All day of month
$dateopt_arr=date('M-N-Y',strtotime(date('M-'.$i.'-Y')));
$dateo=explode('-',$dateopt_arr);
//echo $dateo[1];
if(($dateo[1]%7)==0)
{
echo $first_day_this_month = date('M-D-Y',strtotime(date('M-'.$i.'-Y')))." = ".date('M-d-Y',strtotime(date('M-'.$i.'-Y')));//Week day of month
echo "<br>";
}
}
?>
Use the second argument of strtotime to specify the date to calculate "next Sunday" and other relative dates from:
strtotime('next Sunday', strtotime('09/12/2013'));
http://us2.php.net/strtotime
Example:
echo date('m/d/Y', strtotime('next Sunday', strtotime('09/12/2013')));

Categories