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')));
Related
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
I am actually trying to make a monthly reward system with a "stamp" interface.
For that, I want to use an HTML Table with 1 cell = 1 day, starting Monday.
Here is my problem (and the solution is probably easy to find !) : Monday isn't the first day of month - not for all month, atleast. How can I ask strtotime() & date() to show the date Y-m-d for :
"monday of first week of month" ?
"sunday of last week of month" ?
I'm expecting result like this for 2019-08 :
2019-07-29
2019-09-01
I did not find it on PHP Documentation but is there a way to place a third argument on date() to set up the date ?
Like that, I could have done something like this :
date('Y-m-d', strtotime('monday'), '2019-08-01');
EDIT :
Based on #Vidal answer here is what I tried, but I got a strange PHP reaction :
$first_date = date("Y-m-d", strtotime("first monday 2019-08 - 7 days"));
$last_date = date("Y-m-d", strtotime("last sunday 2019-09"));
$last_date2 = date("Y-m-d", strtotime("last sunday 2019-09 + 7 days"));
echo $first_date; ?><br>
echo $last_date; ?><br>
echo $last_date2; ?><br>
Output :
2019-07-29
2019-08-25
2019-09-08
I don't know why. Did you also notice that I need to set $last_date & $last_date2 to 2019-09 instead of 2019-08 ?
I think it's better to work with the DateTime object.
/*
I'm expecting result like this for 2019-08 :
"monday of first week of month" => 2019-07-29
"sunday of last week of month" => 2019-09-01
*/
$month = "2019-08";
$date = date_create($month."-02")
->modify("last Monday")
->format('l, d-m-Y')
;
echo $date."<br>";
$date = date_create("last Day of ".$month)
->modify("-1 Day")
->modify("next Sunday")
->format('l, d-m-Y')
;
echo $date."<br>";
/* Output
Monday, 29-07-2019
Sunday, 01-09-2019
*/
Do a loop for year, month.
echo date("j, d-M-Y", strtotime("first monday of 2019-08"));
echo date("j, d-M-Y", strtotime("last sunday of 2019-08"));
Hope it helps.
PHP Reference
I managed to make it work by changing some things to your code:
1) If the first monday is > 2 and <= 7, you have to remove 7 days to actually get the first monday
2) I added the '+ 7 days' on another line of code. It didn't work if I had 'last sunday of XXXX-XX + 7 days'
3) To get the last sunday based on your desired outputs, I compared the last sunday of the month with the total number of days in the month - 7. If it's bigger than that (25 for example), it means that it's not the last sunday
$year = 2019;
$month = 8;
if($month < 10)
$month = "0" . $month;
$currentDate = $year . "-" . $month;
if(date("d", strtotime("first monday of " . $currentDate)) > 2 && date("d", strtotime("first monday of " . $currentDate)) <= 7)
$first_date = date("Y-m-d", strtotime("first monday of " . $currentDate . " -7 days"));
else
$first_date = date("Y-m-d", strtotime("first monday of " . $currentDate));
if(date("d",strtotime("last sunday of " . $currentDate)) > date('t') - 7)
{
$last_date = date("Y-m-d", strtotime("last sunday of " . $currentDate));
$last_date = date("Y-m-d",strtotime($last_date . " +7 days")); //working when you add days like that. doesn't work if I put + 7 days in the 'last sunday of'...
}
else
$last_date = date("Y-m-d", strtotime("last sunday of " . $currentDate));
echo $first_date . "<br>";
echo $last_date . "<br>";
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');
I have to get a date which is 6 months added with specific date.
I used the following code
$start_date = "2016-08-30";
$end_date= date( "Y-m-d", strtotime( "$start_date +6 months" ) );
echo $end_date;
which gave result as 2017-03-02
Then I changed the start date in code as below
$start_date = "2016-09-01";
$end_date= date( "Y-m-d", strtotime( "$start_date +6 months" ) );
echo $end_date;
which is giving result as 2017-03-01
Why is this happening at first place? Is there anything wrong with my code?
Using Mysql query
SELECT DATE_ADD('2016-08-30', INTERVAL 6 MONTH)
gives result 2017-02-28
Which is the right solution to get the correct date?
This happens due to PHP's behavior. In this case 6 months are added which gives february(it has 28 days) so it adds three more days , but in MySQL it adds only months.
To solve this use last day of 6 month or last day of sixth month instead of +6 months
Code
$date = new DateTime( '2016-08-30' );
echo $date->format( 'Y-m-d' ), "\n";
$date->modify( 'last day of sixth month' );
echo $date->format( 'Y-m-d' ), "\n";
Code Demo
Output
2016-08-30
2017-02-28
Another Solution
$date = new DateTime( '2016-08-25' );
echo $date->format('Y-m-d'),"\n";
$day = $date->format('j');
$date->modify('first day of sixth month');
$date->modify('+' . (min($day, $date->format('t')) - 1) . ' days');
echo $date->format('Y-m-d');
Code Demo
Output
2016-08-25
2017-02-25
Also refer Relative Formats
This function DOES NOT work from left-to-right as one would think. This function parses the string as a whole, then applies the intervals by size (year, month, ...). Take the following example:
<?php
$Date = strtotime('2011-02-22'); // February 22nd, 2011. 28 days in this month, 29 next year.
echo date('n/j/Y', strtotime('+1 year, +7 days', $Date)); // add 1 year and 7 days. prints 2/29/2012
echo "<br />";
echo date('n/j/Y', strtotime('+7 days, +1 year', $Date)); // add 7 days and 1 year, but this also prints 2/29/2012
echo "<br />";
echo date('n/j/Y', strtotime('+1 year', strtotime('+7 days', $Date))); // this prints 3/1/2012, what the 2nd would do if it was left-to-right
?>
I want to find the timestamp for the most recent 8am encountered. (weekdays only)
For example if its Friday at 3pm I want the timestamp for 8am.
I can do that simply enough, but what about if it is Saturday at 2am.
Also if it is Monday at 6am I want to find Friday at 8am still.
Tried the following:
$timestamp = strtotime(date('Y-m-d') . '08:00:00');
But clearly that only accounts for the current day.
This should do it:
// Choose today if it's past 08:00 and it's not a weekend
if( date( 'G' ) >= 8 && date( 'N' ) <= 5 ) {
$timestamp = strtotime( date( 'Y-m-d' ).' 08:00' );
}
else {
$timestamp = strtotime( 'last weekday 08:00' );
}