Then I guess the logic you are looking for is slightly different? I’m not sure what your use-case is here? Can you explain what you want a bit more?
Obviously, there is no 30th Feb, so when you try to set that date, php sets it to the 1st of March, meaning you’d end up with the 1st Feb in your calculations. I don’t think it’s php that’s wrong here though - it’s just that your logic is different to actually subtracting a month from another month, for whatever reason.
No PHPs treating it correctly in most cases. I’m sure I’d be way past this if the flu didn’t have me down. I’m writing a script for billing cycle statistics. What happened during their previous billing cycle. So on the 28th of every month, I’ll be kicking off this calculation for the 28th, 29th, 30th and 31st because not every month has those, however they still need to roll all the way back to what would be exactly 1 month ago according to their bill cycle.
Drats! I had hoped it may have inherited DateTime to fix some of the idiosyncrasies, but alas it doesn’t, it just adds additional methods. Not really worth the footprint (in my opinion, but neat nonetheless). This is where I wish PHP took a lesson from the .NET framework. Subtracting one month from 2012-03-31 produces 2012-02-29 appropriately in .NET, PHP instead calculates 2012-02-31 and then pushes that to 2012-03-02, which is annoying.
I wound up just passing $day and $month into a function. Thanks for the go at it cp, though it doesn’t do what I need it to. (ex. Feb 15th should return Jan 15th.) This was pretty much just me complaining about my inability to work through anything on a flu
I disagree wholeheartedly. When you subtract a month, you expect to be in the previous month, not still in the current month. Saying 2012-03-31 minus a month is 2012-03-02 is misleading at best. You should be subtracting the 31 days of March to get to February 29th, as that is the month you are trying to lose. When you are 2012-02-29 and you subtract a month, you should remove the 29 days of February to get to January 31st.
The 29th of February would be 1 month prior to the end of March. Remember a Month is not a fixed interval, the size of a month differs by month and by year (in case of leap year).
You may be able to use $date->modify(‘15 of previous month’); but I haven’t tested that to be sure.
So by your math, A month before May 30 is April 29th. Uhm… what? (31 days in May)
Think you meant you need to subtract the number of days in the -preceding- month. Which is how you end up with March 2nd.
I see your point, so my basis is flawed to. PHP is currently subtracting the number of days in the preceding month, thus the March 31st minus a month is March 2nd, which is still wrong… So obviously it is a bit more complex than that too.
This is why I agree with .NET:
[highlight=c#]var march = new DateTime(2012, 03, 31);
var may = new DateTime(2012, 05, 31);
var april = may.AddMonths(-1);
var march = new DateTime(2012, 03, 31);
var february = march.AddMonths(-1);
var january = february.AddMonths(-1);
2012-01-29 // this one irks me a bit, but it is understandable.
I have to give it to the MS folks, they really made it nice and maybe I just expect other languages to do it as well.
I started to replacing the month area by hand in a string, but then I realized it’s not taking care of the year scenario. Should I just write in a case statement, if my starting month is January, subtract from the year?