PHP: Discover if day resides in the last week of the month - php

A client wants a newsletter to be automatically generated every Monday, showing the schedule for the upcoming week. That's easy:
if(date('N', $time)==1) { /* Stuff */ }
Attach that to a crontab running nightly and I'm good to go.
However, if the newsletter is being generated in the last week of the month, it needs to show the schedule for the upcoming month. How would I determine when the monthly schedule needs to be generated?

date('m') == date('m', strtotime('+1 week'))
If the month a week from the date the report is running is different than the current month, show the report!

if(date('n', $time) !== date('n', $time+518400)){
// Six days from now it will be a new month
}

One way might be to see if next Monday is in a different month.
if (date('n', $time) != date('n', $time + 7*24*60*60)) { ... }
You could be fancier, but this seems consistent with your existing code.

You can use the t date format param to see how many days are in the particular month. Try
if ((date('t', $time) - date('j', $time)) > 6) {
// in the last week of the month
}

I know this a answered but this will help more:
PHP's built-in time functions make this even simple. http://php.net/manual/en/function.strtotime.php
// Get first Friday of next month.
$timestamp = strtotime('first fri of next month');
// Get second to last Friday of the current month.
$timestamp = strtotime('last fri of this month -7 days');
// Format a timestamp as a human-meaningful string.
$formattedDate = date('F j, Y', strtotime('first wed of last month'));

Related

Is there a way to get the x-th day of the next month in PHP?

I need to get the 4th day of the next month in PHP. Should be able to generate the date using strtotime()
I followed https://www.php.net/manual/en/datetime.formats.relative.php
tried strtotime('first day of next month +4 days') but it returns first day of next month always because of the precendence I think.
Here is a code you can try. It is my hope that this will work for you
<?php
$d1 = date("Y-m-d", strtotime('first day of next month'));
echo date('Y-m-d', strtotime('+3 days', strtotime($d1)));
Thanks.

Calculate date of last day of month before a target date

I can add any number of months to a date:
strtotime("+ 1 months", '2017-01-31') // result: 2017-03-03
But I want to do this without going to the next month.
in this case I want the result 2017-02-28, that is, the last day of the month before the target month.
There seems to be a lot of overcomplicating in these answers. You want the last day of the month before your target month, which is also always going to be 1 day before the first day of the target month. This can be expressed quite simply:
$months = 1;
$relativeto = '2017-01-31';
echo date(
'Y-m-d',
strtotime(
'-1 day',
strtotime(
date(
'Y-m-01',
strtotime("+ $months months", strtotime($relativeto))
)
)
)
);
Try using the DateTime object like so:
$dateTime = new \DateTime('2017-01-31');
$dateTime->add(new \DateInterval('P1M'));
$result = $dateTime->format('Y-m-d');
Use PHP's DateTime to accomplish this, specifically the modify() method.
$date = new DateTime('2006-12-12');
$date->modify('+1 month');
echo $date->format('Y-m-d');
If the idea here is not to allow the date to overflow into the next month, which PHP does, then you'll have to impose that constraint in your logic.
One approach is to check the modified month against the given month before returning the updated date.
function nextMonth(DateTimeImmutable $date) {
$nextMonth = $date->add(new DateInterval("P1M"));
$diff = $nextMonth->diff($date);
if ($diff->d > 0) {
$nextMonth = $nextMonth->sub(new DateInterval("P{$diff->d}D"));
}
return $nextMonth;
}
$date = new DateTimeImmutable("2017-01-31");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
//2017-01-31 - 2017-02-28
$date = new DateTimeImmutable("2017-10-31");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
//2017-10-31 - 2017-11-30
The nextMonth() function in the example above, imposes the constraint of not overflowing into the next month. Note that what PHP actually does is try to find the corresponding day, in the following consecutive number of months added, not just add a given number of months to the existing date. I simply undo this last part by subtracting any additional days beyond the 1 month interval in the function above.
So for example, strtotime("+1 month") for the date "2017-01-31", tells PHP find the 31st day that is +1 month from "2017-01-31". But of course, there are only 28 days in February, so PHP goes into March and counts up 3 more days to compensate.
In other words, it's not just add +1 month to this date, but add +1 month to this date and arrive at the same day of the month as is in the given date. Which is where the overflow happens.
Update
Since you've now made it clear that you actually want the last day of the month (not necessarily the same day of the next month without the overflow provision) you should instead just explicitly set the day of the month.
function nextMonth(DateTimeImmutable $date) {
$nextMonth = $date->setDate($date->format('Y'), $date->format('n') + 1, 1);
$nextMonth = $date->setDate($nextMonth->format('Y'), $nextMonth->format('n'), $nextMonth->format('t'));
return $nextMonth;
}
$date = new DateTimeImmutable("2017-02-28");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
// 2017-02-28 - 2017-03-31

php: strtotime("12/31/2004 +6 month")); not returning the last day of June

I expected this functional to return 6/30/2005 instead of 7/1/2005.
print date("m/d/Y", strtotime("12/31/2004 +6 month"));
Similarly, print date("m/d/Y", strtotime("1/31/2011 +1 month")) returns 03/03/2011 while would like it to return 2/28/2011.
Does anyone know if there is a straight forward way to show the last day of the added month?
How about this?
echo date("m/d/Y", strtotime("last day of 12/31/2004 + 6 month")); // 6/30/2005
echo date("m/d/Y", strtotime("last day of 1/31/2011 + 1 month")); // 2/28/2011
Demo
Edit: For your reference, here is a link to the documentation for relative times.
as strtotime continue in to next month if there isn't enoghe days that month,
you can back 6 month and check if its end up on the start date
$date2 = date("Y-m-d", strtotime("{$date} +6 months"));
$date3 = date("Y-m-d", strtotime("{$date2} -6 months"));
if($date3 != $date)
{
$date2 = date("Y-m-t", strtotime("{$date2} -1 months"));
}
(or in your case "m/t/Y")
One simple way is to actually go one month ahead of the day you want and then make the day value zero. Also, mktime() might be easier
$mymonth = 2; // I want the last day of February
echo date('m/d/Y', mktime(0,0,0,$mymonth+1,0,2011));
This should return 2/28/2011.
strtotime does the best it can with conflicting information. Saying
1/31/2011 +1month
would mean advancing to
2/31/2011
but February only has 28 (sometimes 29) days. 2011 isn't a leap year, so the "31st of February" gets normalized to "March 3rd".
The same applies for '12/31/2004 +6month'. That takes you to June 31st, 2005. But June only has 30 days, so the date is normalized to July 1st instead.

how to find date of last thursday of the month in php?

how to find date of last thursday of the month in php ?
it is for the payment thing. staffs needs to paid on last thursday of the month on which they have submitted invoices. I am having hard time finding out the date of last thursday of month
thanks
abhinab
PHP >= 5.3:
<?php
$date = strtotime('last thu of this month');
echo date('d.m.Y H:i:s', $date);
PHP < 5.3:
<?php
$date = strtotime(sprintf('+1 month %s %s', date('F'), date('Y')));
while (date('D', $date) !== 'Thu') {
$date -= 86400;
}
echo date('d.m.Y H:i:s', $date);
(didn't find a better way to do this)
Output:
30.06.2011 00:00:00
Find the first day of the month right after.
Walk backwards one day at a time until you hit a Thursday.

How to get previous month and year relative to today, using strtotime and date?

I need to get previous month and year, relative to current date.
However, see following example.
// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));
// Output:
2011-03-02
This behavior is understandable (to a certain point), due to different number of days in february and march, and code in example above is what I need, but works only 100% correctly for between 1st and 28th of each month.
So, how to get last month AND year (think of date("Y-m")) in the most elegant manner as possible, which works for every day of the year? Optimal solution will be based on strtotime argument parsing.
Update. To clarify requirements a bit.
I have a piece of code that gets some statistics of last couple of months, but I first show stats from last month, and then load other months when needed. That's intended purpose. So, during THIS month, I want to find out which month-year should I pull in order to load PREVIOUS month stats.
I also have a code that is timezone-aware (not really important right now), and that accepts strtotime-compatible string as input (to initialize internal date), and then allows date/time to be adjusted, also using strtotime-compatible strings.
I know it can be done with few conditionals and basic math, but that's really messy, compared to this, for example (if it worked correctly, of course):
echo tz::date('last month')->format('Y-d')
So, I ONLY need previous month and year, in a strtotime-compatible fashion.
Answer (thanks, #dnagirl):
// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01
Have a look at the DateTime class. It should do the calculations correctly and the date formats are compatible with strttotime. Something like:
$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02
if the day itself doesn't matter do this:
echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));
I found an answer as I had the same issue today which is a 31st. It's not a bug in php as some would suggest, but is the expected functionality (in some since). According to this post what strtotime actually does is set the month back by one and does not modify the number of days. So in the event of today, May 31st, it's looking for April-31st which is an invalid date. So it then takes April 30 an then adds 1 day past it and yields May 1st.
In your example 2011-03-30, it would go back one month to February 30th, which is invalid since February only has 28 days. It then takes difference of those days (30-28 = 2) and then moves two days past February 28th which is March 2nd.
As others have pointed out, the best way to get "last month" is to add in either "first day of" or "last day of" using either strtotime or the DateTime object:
// Today being 2012-05-31
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d');
// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month"));
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');
So using these it's possible to create a date range if your making a query etc.
If you want the previous year and month relative to a specific date and have DateTime available then you can do this:
$d = new \DateTimeImmutable('2013-01-01', new \DateTimeZone('UTC'));
$firstDay = $d->modify('first day of previous month');
$year = $firstDay->format('Y'); //2012
$month = $firstDay->format('m'); //12
date('Y-m', strtotime('first day of last month'));
strtotime have second timestamp parameter that make the first parameter relative to second parameter. So you can do this:
date('Y-m', strtotime('-1 month', time()))
if i understand the question correctly you just want last month and the year it is in:
<?php
$month = date('m');
$year = date('Y');
$last_month = $month-1%12;
echo ($last_month==0?($year-1):$year)."-".($last_month==0?'12':$last_month);
?>
Here is the example: http://codepad.org/c99nVKG8
ehh, its not a bug as one person mentioned. that is the expected behavior as the number of days in a month is often different. The easiest way to get the previous month using strtotime would probably be to use -1 month from the first of this month.
$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));
I think you've found a bug in the strtotime function. Whenever I have to work around this, I always find myself doing math on the month/year values. Try something like this:
$LastMonth = (date('n') - 1) % 12;
$Year = date('Y') - !$LastMonth;
date("m-Y", strtotime("-1 months"));
would solve this
Perhaps slightly more long winded than you want, but i've used more code than maybe nescessary in order for it to be more readable.
That said, it comes out with the same result as you are getting - what is it you want/expect it to come out with?
//Today is whenever I want it to be.
$today = mktime(0,0,0,3,31,2011);
$hour = date("H",$today);
$minute = date("i",$today);
$second = date("s",$today);
$month = date("m",$today);
$day = date("d",$today);
$year = date("Y",$today);
echo "Today: ".date('Y-m-d', $today)."<br/>";
echo "Recalulated: ".date("Y-m-d",mktime($hour,$minute,$second,$month-1,$day,$year));
If you just want the month and year, then just set the day to be '01' rather than taking 'todays' day:
$day = 1;
That should give you what you need. You can just set the hour, minute and second to zero as well as you aren't interested in using those.
date("Y-m",mktime(0,0,0,$month-1,1,$year);
Cuts it down quite a bit ;-)
This is because the previous month has less days than the current month. I've fixed this by first checking if the previous month has less days that the current and changing the calculation based on it.
If it has less days get the last day of -1 month else get the current day -1 month:
if (date('d') > date('d', strtotime('last day of -1 month')))
{
$first_end = date('Y-m-d', strtotime('last day of -1 month'));
}
else
{
$first_end = date('Y-m-d', strtotime('-1 month'));
}
If a DateTime solution is acceptable this snippet returns the year of last month and month of last month avoiding the possible trap when you run this in January.
function fn_LastMonthYearNumber()
{
$now = new DateTime();
$lastMonth = $now->sub(new DateInterval('P1M'));
$lm= $lastMonth->format('m');
$ly= $lastMonth->format('Y');
return array($lm,$ly);
}
//return timestamp, use to format month, year as per requirement
function getMonthYear($beforeMonth = '') {
if($beforeMonth !="" && $beforeMonth >= 1) {
$date = date('Y')."-".date('m')."-15";
$timestamp_before = strtotime( $date . ' -'.$beforeMonth.' month' );
return $timestamp_before;
} else {
$time= time();
return $time;
}
}
//call function
$month_year = date("Y-m",getMonthYear(1));// last month before current month
$month_year = date("Y-m",getMonthYear(2)); // second last month before current month
function getOnemonthBefore($date){
$day = intval(date("t", strtotime("$date")));//get the last day of the month
$month_date = date("y-m-d",strtotime("$date -$day days"));//get the day 1 month before
return $month_date;
}
The resulting date is dependent to the number of days the input month is consist of. If input month is february (28 days), 28 days before february 5 is january 8. If input is may 17, 31 days before is april 16. Likewise, if input is may 31, resulting date will be april 30.
NOTE: the input takes complete date ('y-m-d') and outputs ('y-m-d') you can modify this code to suit your needs.

Categories