Photo by RODRIGO GONZALEZ on Unsplash
Our PHP TimeTraveler to address DateTime::modify() pitfalls
And some tips & tricks to modify dates with PHP
Everybody knows the PHP native method DateTime::modify()
The DateTime
extension supports awesome modifiers like "2 days ago", "last day of this month", ... or basic ones like "+1 month".
But the last one is actually tricky: it increments the month value of the date.
For instance 2023-01-01 (January first) becomes 2023-(01+1)-01 => 2023-02-01
But as not all months last 31 days: incrementing one month on 2023-08-31 results to 2023-09-31 which doesn't exist and is thus corrected to 2023-10-01.
If you keep playing, you will notice that modify('+1 year')
returns a different date than calling 12 times modify('+1 month')
🤯
(new DateTime('2023-01-31'))->modify('+1 year'); // 2024-01-31
(new DateTime('2023-01-31'))
->modify('+1 month') // 2023-03-03 which is the root cause
...
->modify('+1 month'); // 2024-02-03
At AssoConnect, we deal with monthly and yearly subscriptions, memberships, ... so we need reliable and predictable date operations.
The latest release of our https://github.com/assoconnect/php-date library brings a month & year traveler with 3 main features:
The last day of the month is sticky
September, 30th + 1 month = October, 31st instead of 30th
A month is never skipped
January, 30th + 1 month = February, 28th (or 29th) instead of March, 1st
February, 29th + 1 year = February, 28th instead of March, 1st
The year-over-year result is consistent with the initial reference
January, 30th + (1 month) x 12 = January, 30th instead of February, 2nd
We published this library under the MIT license so feel free to use it!