Reputation: 925
I'm trying to create Datetime
3 days after last day of this month based on date from constructor with this code:
(new Datetime('2019-01-01'))->modify('last day of this month, +3 days')->format('Y-m-d')
so expected output is 2019-02-03
but 2019-01-31
is given.
Consider this code works like charm
(new Datetime('2019-01-01'))->modify('+1 days, +3 days')->format('Y-m-d')
expected: 2019-01-05
given: 2019-01-05
and this also works as well:
(new Datetime('2019-01-01'))->modify('last day of this month, +3 hours')->format('Y-m-d H')
expected: 2019-01-31 03
given 2019-01-31 03
Question: It's a bug or feature? Or maybe using last day of this month
blocks next days
modifications?
Upvotes: 2
Views: 202
Reputation: 276
It is noted in the documentation for Relative Formats where it says:
Note that expressions such as “last day of” and “first day of” imply a day of a month, not, for example of the year or week.
So, expressions, such as “first day of this year” will give the first day of this month, with no apparent regard for the year.
As powerful as the parser is, it can lead to disappointing or confusing results.
It is likely that it is taking priority of the phrase "Last day of" and ignoring the rest of the day statement, even though it's comma separated. As for why it is parsing the time, is it likely parses time effects first, then looks for day effects. The source-code for the functionality can be investigated deeper as to why this is happening. One thing to note is how the first and last day phrases are scanned
firstdayof | lastdayof
{
DEBUG_OUTPUT("firstdayof | lastdayof");
TIMELIB_INIT;
TIMELIB_HAVE_RELATIVE();
/* skip "last day of" or "first day of" */
if (*ptr == 'l' || *ptr == 'L') {
s->time->relative.first_last_day_of = TIMELIB_SPECIAL_LAST_DAY_OF_MONTH;
} else {
s->time->relative.first_last_day_of = TIMELIB_SPECIAL_FIRST_DAY_OF_MONTH;
}
TIMELIB_DEINIT;
return TIMELIB_LF_DAY_OF_MONTH;
}
The pointer only looks at whether or not there's an l or L so it seems to be cutting some corners there.
Upvotes: 1