This question already has answers here:
Add X Days To Date, Excluding Weekends
(5 answers)
Closed 3 years ago.
I want to find an end date of my first date.
For example my first date is
2020-01-01 04:20:18
And I want to get 20 days after this first date but only the weekdays (exclude the saturday and sunday)
I created this
$expirationDate = date_format(date_add(date_create(date("Y-m-d H:i:s",strtotime($_POST['created_at']))),date_interval_create_from_date_string("20 day")),'Y-m-d H:i:s');
The result I got is
2020-01-21 04:20:18
The end date result should be
2020-01-28 04:20:18
Because date 4,5,11,12,18,19,25,26 is saturday and sunday.
Anyone can help me?
You can use a loop and check which day of the week it is to achieve this. I've left your original $expirationDate calculation in to show the difference in the output:
$dt = date("Y-m-d H:i:s", strtotime('2020-01-01 04:20:18'));
$expirationDate = date_format(date_add(date_create($dt),date_interval_create_from_date_string("20 day")),'Y-m-d H:i:s');
// Add 20 days
for ($i = 0; $i < 20; $i++) {
$dt = date("Y-m-d H:i:s", strtotime("+1 day", strtotime($dt)));
// Is it a Sunday or Saturday?
$day = date('w', strtotime($dt));
if ($day == 0 || $day == 6)
// Deduct one from loop counter
$i--;
}
// Output
echo $dt;
echo $expirationDate;
Output:
$dt = 2020-01-29 04:20:18 (correct)
$expirationDate = 2020-01-21 04:20:18 (incorrect)
How does it work?
It's quite straight-forward:
Store the start date in $dt
Loop from 0 to 19 (for 20 days)
Add one day to $dt
If the day is a Sunday (0) or a Saturday (6), subtract 1 from the loop counter ($i)
An Alternative Solution
As an alternative, this may be greatly simplified by simply adding four weeks to the start time:
$dt = date("Y-m-d H:i:s", strtotime('2020-01-01 04:20:18'));
$dt = date("Y-m-d H:i:s", strtotime("+4 week", strtotime($dt)));
echo $dt;
However, this could only work if that start date was guaranteed to be a weekday. Otherwise you'd end up with an end date on a weekend.
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
I have tried :
$firstOfMonth = "2015-01-01";
$last_month = date("Y-m-d", strtotime('first day of -1 month', strtotime($firstOfMonth)));
/* ^^^^^ This gives me 01 of last month */
/*** Tried 'seventh day of -1 month'
/* it gives 1970-01-01
*/
What I want is to get the 07 of last month.
uhm....the first day of a month is allways 01....so basically you only need year and month:
$firstOfMonth = "2015-01-01";
$last_month = date("Y-m-01",strtotime("-1 month",strtotime($firstOfMonth)));
Just like Mr.Manhattan said, you just need the year and month and to the seventh day you can leave it hard coded or in a variable:
date("Y-m-07",strtotime("-1 month"));
$fixedDay = '07';
echo date("Y-m-$fixedDay",strtotime("-1 month"));
So, in PHP i'm trying to return a date value for last year based on the same day of week.
EX: (Monday) 2011-12-19 inputted should return (Monday) 2010-12-20.
I was just doing it simply by -364 but then that was failing on leap years. I came across another function :
$newDate = $_POST['date'];
$newDate = strtotime($newDate);
$oldDate = strtotime('-1 year',$newDate);
$newDayOfWeek = date('w',$oldDate);
$oldDayOfWeek = date('w',$newDate);
$dayDiff = $oldDayOfWeek-$newDayOfWeek;
$oldDate = strtotime("$dayDiff days",$oldDate);
echo 'LAST YEAR DAY OF WEEK DATE = ' . date('Ymd', $oldDate);
however, that is failing when you try to input a Sunday date, as it does a 0 (sunday) minus 6 (saturday of last year date), and returns with a value T-6. IE inputting 2011-12-25 gets you 2010-12-19 instead of 2011-12-26.
I'm kind of stumped to find a good solution in php that will work for leap years and obviously all days of the week.
Any suggestions?
Thanks!
How about this, using PHP's DateTime functionality:
$date = new DateTime('2011-12-25'); // make a new DateTime instance with the starting date
$day = $date->format('l'); // get the name of the day we want
$date->sub(new DateInterval('P1Y')); // go back a year
$date->modify('next ' . $day); // from this point, go to the next $day
echo $date->format('Ymd'), "\n"; // ouput the date
$newDate = '2011-12-19';
date_default_timezone_set('UTC');
$newDate = strtotime($newDate);
$oldDate = strtotime('last year', $newDate);
$oldDate = strtotime(date('l', $newDate), $oldDate);
$dateFormat = 'Y-m-d l w W';
echo "This date: ", date($dateFormat, $newDate), "\n";
echo "Old date : ", date($dateFormat, $oldDate);
That gives:
This date: 2011-12-19 Monday 1 51
Old date : 2010-12-20 Monday 1 51
Use strtotime() to get a date, for the same week last year.
Use the format {$year}-W{$week}-{$weekday}, like this:
echo date("Y-m-d", strtotime("2010-W12-1"));
And you can do that for as long back you wan't:
<?php
for($i = 2011; $i > 2000; $i--)
echo date("Y-m-d", strtotime($i."-W12-1"));
?>
Make it easier :)
echo date('Y-m-d (l, W)').<br/>;
echo date('Y-m-d (l, W)', strtotime("-52 week"));
Edit: I forgot to write output: :)
2015-05-06 (Wednesday, 19)
2014-05-07 (Wednesday, 19)
<?php
$date = "2020-01-11";
$newdate = date("Y-m-d",strtotime ( '-1 year' , strtotime ( $date ) )) ;
echo $newdate;
?>
ref https://www.nicesnippets.com/blog/how-to-get-previous-year-from-date-in-php
I have two columns in my db: start_date and end_date, which are both DATE types. My code is updating the dates as follows:
$today_date = date("Y-m-d");
$end_date = date("Y-m-d"); // date +1 month ??
$sql1 = "UPDATE `users` SET `start_date` = '".$today_date."', `end_date` = '".$end_date."' WHERE `users`.`id` ='".$id."' LIMIT 1 ;";
What is the best way to make $end_date equal to $start_date + one month? For example, 2000-10-01 would become 2000-11-01.
You can use PHP's strtotime() function:
// One month from today
$date = date('Y-m-d', strtotime('+1 month'));
// One month from a specific date
$date = date('Y-m-d', strtotime('+1 month', strtotime('2015-01-01')));
Just note that +1 month is not always calculated intuitively. It appears to always add the number of days that exist in the current month.
Current Date | +1 month
-----------------------------------------------------
2015-01-01 | 2015-02-01 (+31 days)
2015-01-15 | 2015-02-15 (+31 days)
2015-01-30 | 2015-03-02 (+31 days, skips Feb)
2015-01-31 | 2015-03-03 (+31 days, skips Feb)
2015-02-15 | 2015-03-15 (+28 days)
2015-03-31 | 2015-05-01 (+31 days, skips April)
2015-12-31 | 2016-01-31 (+31 days)
Some other date/time intervals that you can use:
$date = date('Y-m-d'); // Initial date string to use in calculation
$date = date('Y-m-d', strtotime('+1 day', strtotime($date)));
$date = date('Y-m-d', strtotime('+1 week', strtotime($date)));
$date = date('Y-m-d', strtotime('+2 week', strtotime($date)));
$date = date('Y-m-d', strtotime('+1 month', strtotime($date)));
$date = date('Y-m-d', strtotime('+30 days', strtotime($date)));
The accepted answer works only if you want exactly 31 days later. That means if you are using the date "2013-05-31" that you expect to not be in June which is not what I wanted.
If you want to have the next month, I suggest you to use the current year and month but keep using the 1st.
$date = date("Y-m-01");
$newdate = strtotime ( '+1 month' , strtotime ( $date ) ) ;
This way, you will be able to get the month and year of the next month without having a month skipped.
You do not actually need PHP functions to achieve this. You can already do simple date manipulations directly in SQL, for example:
$sql1 = "
UPDATE `users` SET
`start_date` = CURDATE(),
`end_date` = DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
WHERE `users`.`id` = '" . $id . "';
";
Refer to http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_addtime
If you want a specific date in next month, you can do this:
// Calculate the timestamp
$expire = strtotime('first day of +1 month');
// Format the timestamp as a string
echo date('m/d/Y', $expire);
Note that this actually works more reliably where +1 month can be confusing. For example...
Current Day | first day of +1 month | +1 month
---------------------------------------------------------------------------
2015-01-01 | 2015-02-01 | 2015-02-01
2015-01-30 | 2015-02-01 | 2015-03-02 (skips Feb)
2015-01-31 | 2015-02-01 | 2015-03-03 (skips Feb)
2015-03-31 | 2015-04-01 | 2015-05-01 (skips April)
2015-12-31 | 2016-01-01 | 2016-01-31
Adding my solution here, as this is the thread that comes in google search. This is to get the next date of month, fixing any skips, keeping the next date within next month.
PHP adds current months total number of days to current date, if you do +1 month for example.
So applying +1 month to 30-01-2016 will return 02-03-2016. (Adding 31 days)
For my case, I needed to get 28-02-2016, so as to keep it within next month. In such cases you can use the solution below.
This code will identify if the given date's day is greater than next month's total days. If so It will subtract the days smartly and return the date within the month range.
Do note the return value is in timestamp format.
function getExactDateAfterMonths($timestamp, $months){
$day_current_date = date('d', $timestamp);
$first_date_of_current_month = date('01-m-Y', $timestamp);
// 't' gives last day of month, which is equal to no of days
$days_in_next_month = date('t', strtotime("+".$months." months", strtotime($first_date_of_current_month)));
$days_to_substract = 0;
if($day_current_date > $days_in_next_month)
$days_to_substract = $day_current_date - $days_in_next_month;
$php_date_after_months = strtotime("+".$months." months", $timestamp);
$exact_date_after_months = strtotime("-".$days_to_substract." days", $php_date_after_months);
return $exact_date_after_months;
}
getExactDateAfterMonths(strtotime('30-01-2016'), 1);
// $php_date_after_months => 02-03-2016
// $exact_date_after_months => 28-02-2016
You can use strtotime() as in Gazler's example, which is great for this case.
If you need more complicated control use mktime().
$end_date = mktime(date("H"), date("i"), date("s"), date("n") + 1, date("j"), date("Y"));
date("Y-m-d",strtotime("last day of +1 month",strtotime($anydate)))
date_trunc('month', now()) + interval '1 month'
date_trunc('month', now()) returns start date of month and + interval '1 month' add a month to date.
This function returns any correct number of months positively or negatively. Found in the comment section here:
function addMonthsToTime($numMonths = 1, $timeStamp = null){
$timeStamp === null and $timeStamp = time();//Default to the present
$newMonthNumDays = date('d',strtotime('last day of '.$numMonths.' months', $timeStamp));//Number of days in the new month
$currentDayOfMonth = date('d',$timeStamp);
if($currentDayOfMonth > $newMonthNumDays){
$newTimeStamp = strtotime('-'.($currentDayOfMonth - $newMonthNumDays).' days '.$numMonths.' months', $timeStamp);
} else {
$newTimeStamp = strtotime($numMonths.' months', $timeStamp);
}
return $newTimeStamp;
}
01-Feb-2014
$date = mktime( 0, 0, 0, 2, 1, 2014 );
echo strftime( '%d %B %Y', strtotime( '+1 month', $date ) );
I think this is similar to kouton's answer, but this one just takes in a timeStamp and returns a timestamp SOMEWHERE in the next month. You could use date("m", $nextMonthDateN) from there.
function nextMonthTimeStamp($curDateN){
$nextMonthDateN = $curDateN;
while( date("m", $nextMonthDateN) == date("m", $curDateN) ){
$nextMonthDateN += 60*60*24*27;
}
return $nextMonthDateN; //or return date("m", $nextMonthDateN);
}
I know - sort of late. But I was working at the same problem. If a client buys a month of service, he/she expects to end it a month later. Here's how I solved it:
$now = time();
$day = date('j',$now);
$year = date('o',$now);
$month = date('n',$now);
$hour = date('G');
$minute = date('i');
$month += $count;
if ($month > 12) {
$month -= 12;
$year++;
}
$work = strtotime($year . "-" . $month . "-01");
$avail = date('t',$work);
if ($day > $avail)
$day = $avail;
$stamp = strtotime($year . "-" . $month . "-" . $day . " " . $hour . ":" . $minute);
This will calculate the exact day n*count months from now (where count <= 12). If the service started March 31, 2019 and runs for 11 months, it will end on Feb 29, 2020. If it runs for just one month, the end date is Apr 30, 2019.
$nextm = date('m', strtotime('+1 month', strtotime(date('Y-m-01'))));
one way of doing this is- first getting last date of current month and then adding 1 day to it, to get next month's first date. This will prevent us from unintentional skipping of months which occurs while using '+1 month'.
$today_date = date("Y-m-d");
$last_date_of_month=date('Y-m-t',strtotime($today_date);//get last date of current month
$last_day_of_month_proper =strtotime($last_day_of_month);
$new_date=date('Y-m-d', strtotime('+1 day',$last_day_of_month_proper));
echo $new_date;