Page MenuHomePhabricator

{{#time | + time interval}} does not give satisfying results at the end of a month
Closed, DeclinedPublic

Description

Author: cepey.x

Description:
In short: {{#time: j F Y | 31 May 2013 + 1 month}} yields "1 July 2013" (31 days after 1 May 2013). It should give "30 June 2013" (the last day of June 2013). The reason is that, when you just extract the month, you get unwanted result with the current behaviour. For example, when "now" is 30 March 2012 14:00 CEST:

  • {{#time: F Y | now}}, gives "March 2012" (correct)
  • {{#time: F Y | now - 1 month}}, gives "March 2012" (incorrect or unwanted)
  • {{#time: F Y | now - 2 months}}, gives "January 2012" (correct)

Version: unspecified
Severity: normal

Details

Reference
bz35608

Event Timeline

bzimport raised the priority of this task from to High.Nov 22 2014, 12:14 AM
bzimport added a project: ParserFunctions.
bzimport set Reference to bz35608.
bzimport added a subscriber: Unknown Object (MLST).

I'm guessing this is because the month component is changed, and then the date "rationalised" to a date that actually exists.

Note that this can also be seen here:

{{#time: j F Y | 32 May 2013}}: Error: Invalid time.
{{#time: j F Y | 31 June 2013}}: 1 July 2013

A month is an ambiguous unit of time, so I'm not sure how this could be reliably fixed for all situations.

This is a PHP bug, closed invalid upstream. https://bugs.php.net/bug.php?id=22486
Nothing we're going to do here, hacking PHP's date functions is something we don't want to expand.

It seems this bug is reported every year on May 31, see discussion below from #wikimedia-tech.


2014-05-31 22.52 < T13|sleeps> Why is {{#time:F Y}} returning "May 2014" & {{#time:F Y|+1 month}} returning "July 2014"? Parser forget about June?
2014-05-31 22.58 < Nemo_bis> T13|sleeps: how many days is +1 month?
2014-05-31 22.59 < T13|sleeps> 1 months worth.
2014-05-31 22.59 < Nemo_bis> 31 May + 31 days = 1st July
2014-05-31 22.59 < Nemo_bis> That's not an answer to my question
2014-05-31 22.59 < Nemo_bis> Unless they forgot to tell you in primary school that not all months have the same number of days,
2014-05-31 22.59 < Reedy> poor Nemo_bis
2014-05-31 22.59 < Nemo_bis> at least in our current calendar
2014-05-31 23.00 < Nemo_bis> If the French had been more convincing in the 18th century it might have been different
2014-05-31 23.00 < T13|sleeps> The parser shouldn't be calculating +1 month as days. It should say this is month 5 +1 is month 6 which is June.
2014-05-31 23.01 < Reedy> Do we just delegate to php?
2014-05-31 23.02 < Reedy> This does feel de ja vu
2014-05-31 23.02 < Krenair> Yeah...
2014-05-31 23.02 < {{Technical_13}}> Sorry, lost connection for a minute.
2014-05-31 23.02 < Krenair> (yes it feels like de ja vu, don't know if we just send it straight to some php function)
2014-05-31 23.03 < {{Technical_13}}> The parser shouldn't be calculating +1 month as days. It should say this is month 5 +1 is month 6 which is June.
2014-05-31 23.03 < Krenair> {{Technical_13}}, yep, we got that bit. next message was your joining so you missed nothing
2014-05-31 23.03 < {{Technical_13}}> Cool
2014-05-31 23.04 < {{Technical_13}}> In my use case I can make a hack to work around the issue, but it will be ugly and not ideal.
2014-05-31 23.04 -!- Newyorkadam [~Newyorkad@wikipedia/Newyorkadam] has joined #wikimedia-tech
2014-05-31 23.05 -!- T13|sleeps [~T13@wikimedia/Technical-13] has quit [Ping timeout: 255 seconds]
2014-05-31 23.05 < Nemo_bis> +1 month is used in combination with all time formats
2014-05-31 23.06 < Nemo_bis> Though it's probably silly to ask what time will it be in current time + 1 month
2014-05-31 23.06 < Reedy> php > var_dump( gmdate("Y-m-d\Z", strtotime( "now + 1 month" ) ) );
2014-05-31 23.06 < Reedy> string(11) "2014-07-01Z"
2014-05-31 23.06 < Reedy> It's not mediawiki
2014-05-31 23.06 < Nemo_bis> Now should we be happy or sad with this :)
2014-05-31 23.07 < Reedy> php > var_dump( gmdate("m", strtotime( "this month" ) ) );
2014-05-31 23.07 < Reedy> string(2) "05"
2014-05-31 23.07 < Reedy> php > var_dump( gmdate("m", strtotime( "next month" ) ) );
2014-05-31 23.07 < Reedy> string(2) "07"
2014-05-31 23.07 < Reedy> that is amusing though
2014-05-31 23.07 < Nemo_bis> seems to be widely discussed
2014-05-31 23.07 < Krenair> Bugs?
2014-05-31 23.07 < Krenair> In PHP's time handling functions?
2014-05-31 23.08 < Reedy> God Bless PHP.
2014-05-31 23.08 < Nemo_bis> https://bugs.php.net/bug.php?id=44073 ?
2014-05-31 23.08 < {{Technical_13}}> I can do something like: {{#time:F Y|{{#expr:{{#time:n}}+1}},15 {{#time:Y}}}}
2014-05-31 23.08 < Reedy> ""first day of +1 month" or "first day of next month" or even "last day of next month" - those are always safe to use with just a "m" or another month date format specifier."
2014-05-31 23.09 < Nemo_bis> "Status: Not a bug" "An existing bug report already describes this very problem"
2014-05-31 23.09 < Nemo_bis> Helpful
2014-05-31 23.09 < Reedy> RESOLVED WORKSFORME
2014-05-31 23.10 < Nemo_bis> https://bugs.php.net/bug.php?id=22486&edit=2
2014-05-31 23.10 < Nemo_bis> Is this really the ultimate answer?
2014-05-31 23.11 < Krenair> Our side of this is ExtParserFunctions which creates a DateTime object
2014-05-31 23.11 < Nemo_bis> I mean, it's not that hard +n months ~ + sum of days of n months after the currentone
2014-05-31 23.12 < Nemo_bis> Ugly but not impossible (hopefully forbidden by some standard?)
2014-05-31 23.12 < Krenair> ExtParserFunctions::time* even