Using strtotime to find date before a date - php

I have a very simple question I would like to pose, but the answer is eluding me. I have a date (such as "first sunday in April") and I am trying to find the day before this, using the php strtotime function. It occurred to me that this would be harder using any other bespoke method as I'd have to take into account the number of days in a month in case (for instance), the first sunday in April was the 1st. Ive tried the obvious solutions like "first sunday in April - 1 day" and "1 day before first Sunday in April".
I'm hoping it can be done in one step rather than find the output of strtotime and then perform arithmetic on its results.
I'm sure it must be simple. Many thanks!

Try the different relative date/time formats at:
http://php.net/manual/en/datetime.formats.relative.php

Related

Carbon PHP Loop through each month on date range [duplicate]

I failed to find a proper solution to this issue. As you see in Example #3 in the PHP documentation, they state that one must beware when adding months using the DateInterval in DateTime::add.
There's not really any explanation for why the method's behavior is as such and what I can do to avoid this, which I find to be an error at first sight.
Anyone have some insight into this?
The issue is that each month can have a different number of days in them. The question is what you're doing when you want to increment a date by 1 month. Per the PHP documentation if you're on January 31st (or 30th) and you add 1 month, what is the expected behavior?
February only has 29 days in it. Do you want to be set to the last day of the month? You're generally safer incrementing by a set number of days if that's what you're looking for, or a static date based on the current date. Without knowing what you're trying to accomplish when you increment your month, it's tough to say how to watch for an error.
EDIT:
As someone mentions in the similar post commented by Mike B above, you probably want to do something where you (in pseudocode):
1) Use cal_days_in_month() for the next month and save that number to a variable x
2) If x >= current billing DOB, increment and be done
3) DateTime::modify('last day') (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)
Worth noting is that if you use the variable here as the new billing value, you'll wipe out your original value. I would save an extra DB value that's "first billing date" or just "billing_day_of_month" or something, and use that to figure out the day of month that you should be looking at
If your goal is to strictly increment by user-friendly months (thus, 3 months from January 21st should be April 21st), with the exception that shorter membership months get shortened (thus, 1 month from January 31st is February 28th/29th), then you only need to go back a few days if you crossed over into the next month:
function addMonths($date,$months) {
$orig_day = $date->format("d");
$date->modify("+".$months." months");
while ($date->format("d")<$orig_day && $date->format("d")<5)
$date->modify("-1 day");
}
$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29

Usage of 'next' in strtotime with multiple relative dates

After looking at the PHP.NET Relative Format Dates page, I'm still confused about the order of operations with multiple relative dates in strtotime when subtracting.
I've noticed that the following returns 1/9/2015.
strtotime('next friday -7 days', strtotime('1/16/2015'))
Yet the following return 1/30/2015.
strtotime('next friday +7 days', strtotime('1/16/2015'))
I would interpret this as since 1/16/2015 is a Friday next Friday would be 1/23/2015 (similiar to how the second strtotime works above). Then we will subtract or add seven days.
As can be seen that doesn't appear to be the case for subtraction. Any more clarification on the ordering of these operations.
Re-writing the code as the following solves the issue (returns 1/16/2015):
strtotime('friday', strtotime('1/16/2015'))
I still think that phrasing above should have worked to find the date of 1/16/2015, so I guess it's something to keep in the back of your mind when using strtotime.

Discussion of `strtotime` problems eg "this x day " when day not = x gives NEXT x. ESOTERIC pls ignore

EDIT: Two minuses in under a minute. I thought this was a tiny but interesting query.
ORIGINAL QUERY: I am generating a five week calender into which I will pour info (the day and date and other stuff).
I want the top left cell to be the "current" Sunday.
For example if today is Weds 12th then I need to find Sun 9th as the start for the run. Then I just do a $var = strtotime("+1 day", $var) for the next 34 slots.
My problem is doing this neatly if today is Sunday.
At present I have:
date_default_timezone_set("Pacific/Honolulu");
$day_now = time();
$current_day= date ("D", $day_now);
if ($current_day == "Sun")
{$day_now = strtotime("+1 day", $day_now);}
$day_now = strtotime("last sunday");
//do stuff/
I just wondered if there was a more "tidy" way of doing this.
I tried "this sunday, last sunday, sunday this week" but could find nothing that would pick today as the Sunday and ALSO work for the rest of the week.
Just curious if anyone has found a form of words that works for this with strtotime.
OK strtotime has NO one phrase solution to the current query ('this sunday" for the whole week). (I would call it a bug!)
The linked discussions
Strange behaviour of strtotime() when using relative dates ('this week')
and
Computing relative dates in php using strtotime()
offer solutions.
I like my current solution - while not elegant it is very readable and I know that if I come back to it in a couple of years I will understand what is going on.
Hopefully "this sunday" will be fixed someday instrtotime.
Thanks for the input.

Use date and/or strtotime() functions in php to identify complex date patterns

I am well versed in using strtotime or the date modify functions within PHP to find NEXT or PREVIOUS days/months/years, or to add or subtract dates. There is the ability to do something like strtotime("first day of last month") but there is not the ability to use a specific month name (let's say July) as a parameter...so it seems I cannot say strtotime("first day of last July").
My question is NOT
"can you write me some code to give me the date"
but rather
"is there a streamlined 1 or 2 line approach using strtotime() or
something else that will enable me to reach the same output with
something more compact, tidy, and clear?"
I am trying to streamline some fairly clunky code to figure out the date (really just the year) of July 1 two instances ago...not the most recent past July 1, but the one a year prior to that (so it could be a date almost 2 full years in the past...or could be as recent as 1 year and 1 day in the past).
For example:
Assume today is February 26, 2014. I am trying to output 2012-07-01.
However a bit later this same year... let's say on July 2 of 2014...
the output would now be 2013-07-01
So, essentially I need to figure out if July 1 has already happened in the current year...and if not then subtract 2 from the current year...and if yes, then subtract 1 from the current year.
A clunky version looks like this:
$CurrentDate = date("Y-m-d");
$CurrentYear = date("Y");
$ThisYearCutOff = $CurrentYear.'-07-01';
if($CurrentDate > $ThisYearCutOff){
echo ($CurrentYear-1).'-07-01';
}
else
{
echo ($CurrentYear-2).'-07-01';
}
Any thoughts on how to do this in a relatively streamlined bit of php code?

What can go wrong when adding months with a DateInterval and DateTime::add?

I failed to find a proper solution to this issue. As you see in Example #3 in the PHP documentation, they state that one must beware when adding months using the DateInterval in DateTime::add.
There's not really any explanation for why the method's behavior is as such and what I can do to avoid this, which I find to be an error at first sight.
Anyone have some insight into this?
The issue is that each month can have a different number of days in them. The question is what you're doing when you want to increment a date by 1 month. Per the PHP documentation if you're on January 31st (or 30th) and you add 1 month, what is the expected behavior?
February only has 29 days in it. Do you want to be set to the last day of the month? You're generally safer incrementing by a set number of days if that's what you're looking for, or a static date based on the current date. Without knowing what you're trying to accomplish when you increment your month, it's tough to say how to watch for an error.
EDIT:
As someone mentions in the similar post commented by Mike B above, you probably want to do something where you (in pseudocode):
1) Use cal_days_in_month() for the next month and save that number to a variable x
2) If x >= current billing DOB, increment and be done
3) DateTime::modify('last day') (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)
Worth noting is that if you use the variable here as the new billing value, you'll wipe out your original value. I would save an extra DB value that's "first billing date" or just "billing_day_of_month" or something, and use that to figure out the day of month that you should be looking at
If your goal is to strictly increment by user-friendly months (thus, 3 months from January 21st should be April 21st), with the exception that shorter membership months get shortened (thus, 1 month from January 31st is February 28th/29th), then you only need to go back a few days if you crossed over into the next month:
function addMonths($date,$months) {
$orig_day = $date->format("d");
$date->modify("+".$months." months");
while ($date->format("d")<$orig_day && $date->format("d")<5)
$date->modify("-1 day");
}
$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29

Categories