Last modified: 2011-04-14 15:10:56 UTC
There are many cases, when it's necessary to count either date +- some period or difference between two dates. Since having {{#expr:}} which allows easy constructing or deconstructing of timestamp, I'd suggest following simple syntax: {{timediff:20060824124500|20070925134601}} = 000101010101 time difference between 24th Aug 2006 12:45:00 and 25th Aug 2007 13:46:01 is 1 year 1 month 1 day 1 hour 1 minute 1 second {{timediff:20060824124500|+000101010101}} = 20070925134601 24th Aug 2006 12:45:00 + 1 year 1 month 1 day 1 hour 1 minute 1 second is 25th Aug 2007 13:46:01 {{timediff:20060824124500|-000101010101}} = 20050723114359 24th Aug 2006 12:45:00 - 1 year 1 month 1 day 1 hour 1 minute 1 second is 23th Jul 2005 11:43:59
Do we have functions that can format the output into a friendlier format? If not, then this will have more limited use.
(In reply to comment #1) > Do we have functions that can format the output into a friendlier format? If > not, then this will have more limited use. Well, I tried to suggest the simpliest and straightest syntax. Formatting output can by done via {{#expr:}} eg.: year = (timestamp - timestamp mod 10000000000) / 10000000000 etc. Creating input is even simplier: timestamp = year * 10000000000 + month * 100000000 + day * 1000000 + hour * 10000 + minute * 100 + second If not such a big issue, another parameter can be added to format the output in common syntax eg.: {{timediff:20060824124500|+000101010101|d. M. yyyy, hh:mm:ss}} but I guess, there would have to be probably only numerical output (no monthnames) or will the i18n be no problem? Going further, there are other possibilities, like: {{decodetimestamp:20060824124500|MM}} = 08 {{decodetimestamp:20060824124500|s}} = 0 etc. or even a set of colon functions like: {{getday:<timestamp>}}, {{getmonth:<timestamp>}} etc... but I don't think, it's necessary to go that far. But the biggest need now at all is to count the time difference. Other things to make it more user friendly can wait for demand, I think.
(In reply to comment #0) Whoups, made a small mistake: 000101010101 should be 00010101010101 (+ one more 01 at the end) of course. Sorry.
I have a better idea: a parser function called #time. It takes one required parameter and one optional parameter. The required parameter is a date format in the style of Language::sprintfDate(), which is the internationalised date formatter I wrote a few weeks ago. The optional parameter is a string date as accepted by strtotime(), the same function we use for block expiries. strtotime() accepts both relative and absolute dates, so it could do timezone conversions. For example, you could find out what time it is here in Melbourne with: {{#time:H:i|+10 hours}} This is very simple to code, just a few lines.
(In reply to comment #4) So what would be the syntax (and output) to get the time difference between two timestamps? {{#time:2006-08-24 14:50:00|2007-09-25 15:51:01}} ? And what should be the output in general? I think the output should be either raw (timestamp) so people can format it the way they want, or the function should allow output formatting parameter, because you don't need precisious time everytime. Couple examples from cs wiki: Certain procedures are being closed tightly to minute, so the precisious time is needed. Certain procedures are being closed in the midnight of counted day, so only date without time is needed.
(In reply to comment #4) > I have a better idea: a parser function called #time. It takes one required > parameter and one optional parameter. The required parameter is a date format in > the style of Language::sprintfDate(), which is the internationalised date > formatter I wrote a few weeks ago. The optional parameter is a string date as > accepted by strtotime(), the same function we use for block expiries. strtotime() > accepts both relative and absolute dates, so it could do timezone conversions. If you do this, how about adding U to the list of supported formatting characters? That would mean date arithmetic would be possible via {{#time: Y-m-d H:i:s|@{{#expr: {{#time:U|2007-09-25 15:51:01}} - {{#time:U|2006-08-24 14:50:00}} }} }}, which is hardly elegant and not particularly efficient but should be usable. (Why not support all PHP's formatting characters anyway? It's not as though cases after the one you hit are going to affect performance, I assume.) (In reply to comment #5) > (In reply to comment #4) > So what would be the syntax (and output) to get the time difference between two > timestamps? As Tim proposed it, it wouldn't be possible that I can see; with the slight emendation I suggested, it would be as I stated above. Note that in either case, the input date (second parameter) can be basically anything that looks like a date: see http://www.gnu.org/software/tar/manual/html_node/tar_109.html for how it decides to parse the formats, but basically you can use most unambiguous date formats and it will figure them out. "2006-08-24 14:50:00" can also be written as "2:50 PM -0500, 24 August 2006", or "200608241450", or whatever.
(In reply to comment #6) > (In reply to comment #5) > > (In reply to comment #4) > > So what would be the syntax (and output) to get the time difference between two > > timestamps? > > As Tim proposed it, it wouldn't be possible that I can see; with the slight > emendation I suggested, it would be as I stated above. Note that in either > case, the input date (second parameter) can be basically anything that looks > like a date: see http://www.gnu.org/software/tar/manual/html_node/tar_109.html > for how it decides to parse the formats, but basically you can use most > unambiguous date formats and it will figure them out. "2006-08-24 14:50:00" can > also be written as "2:50 PM -0500, 24 August 2006", or "200608241450", or whatever. Well, in fact I don't care about syntax of function or date format, just do it the way which is simpliest for you guys to program. The only two things I care about are * output should be either difference between two dates or date + difference (if unnecessary hard to program or considered confusing, just split it into two functions) * output should be formattable to be able to get just certain part (eg. just day) or it should be raw timestamp so people can format it further I'll be totally pleased and satisfied with anything what will allow these two points regardless the final syntax. Thank you guys that you're interested in solving it. I think this feature is being missed by many users.
Wait, one minute, my bad. Tim, {{#time:}} would output a date, not a time interval, so is unsuitable for this purpose. I've split this into bug 7116. A {{#timediff:}} function that will output some kind of time interval is still necessary for many purposes. It shouldn't be hard; something like {{#timediff: date 1 | date 2 | format}} would be what we want, with date 1 and date 2 fed into strtotime() and then format constructed out of characters representing various units, both with and without considering remainders (so S could be the total integer number of seconds in the difference, and s could be the number of seconds modulo 60).
It's now possible, albeit awkward, to calculate date differences. Watch out for [[Wikipedia:Template limit]]. To calculate the floor of the number of years between two dates, for instance, you can use {{#expr: {{#time: Y|first time}} - {{#time: Y|second time}} }}. You can then do the same for days, months, etc., although you'll need more logic to handle negative values.
Referring to comment #9 this bug seems to be FIXED.
(In reply to comment #10) > Referring to comment #9 this bug seems to be FIXED. Definitely not. Bunch of templates with possible excessing of translusion limit instead of one parser function? No, that isn't the purpose.
See, for instance, [[Template:Time ago]]. This is miles off the template limits, and is simple and effective. A specific function #time*diff* would actually be less useful than a function that simply converts a number-of-seconds value into a relative time, but that's not specifically what this bug is about.
(In reply to comment #12) > See, for instance, [[Template:Time ago]]. This is miles off the template > limits, and is simple and effective. A specific function #time*diff* would > actually be less useful than a function that simply converts a > number-of-seconds value into a relative time, but that's not specifically what > this bug is about. > Actually, what exactly would be less useful? Did you read the proposals of behavior? Please, don't close this as FIXED since it is not fixed in fact. I'm also pointing to the fact that PHP 5.3.0 introduces DateTime::diff. So basically this can be left open until a wikisyntax wrapper for that method (as a separate extension probably - thus the entire ParserFunctions wouldn't have to depend on high version of PHP) will be developed.
With the #time and #expr parser functions we can trivially calculate the number of seconds between two dates: {{#expr: {{#time:U|date1}} - {{#time:U|date2}} }} If we had a function #timeformat to match #dateformat, that converted that string into a relative time, then you have your prettified output; as noted in comment7, it would be nice to be able to get only a part of the output. But such a function could also be used to, for instance, convert between units of time (eg {{#timeformat: numberofseconds | Y }} converts seconds to years). Of course this can be done using #expr but guess what, so can #timeformat itself. If you're determined to ignore the fact that this can be quite easily handled on-wiki without any extra bells-and-whistles from the software end, the resulting function might as well be as useful as possible. You're right, I guess, that this bug isn't really FIXED because the available solution is not software-based, but I'd strongly suggest WONTFIX for exactly that reason. It's easily doable on-wiki, without bloating the code with another myserious parser function, and without running into performance issues.
(In reply to comment #14) > With the #time and #expr parser functions we can trivially calculate the number > of seconds between two dates: > > {{#expr: {{#time:U|date1}} - {{#time:U|date2}} }} > > If we had a function #timeformat to match #dateformat, that converted that > string into a relative time, then you have your prettified output; as noted in > comment7, it would be nice to be able to get only a part of the output. But > such a function could also be used to, for instance, convert between units of > time (eg {{#timeformat: numberofseconds | Y }} converts seconds to years). Of > course this can be done using #expr but guess what, so can #timeformat itself. > If you're determined to ignore the fact that this can be quite easily handled > on-wiki without any extra bells-and-whistles from the software end, the > resulting function might as well be as useful as possible. > > You're right, I guess, that this bug isn't really FIXED because the available > solution is not software-based, but I'd strongly suggest WONTFIX for exactly > that reason. It's easily doable on-wiki, without bloating the code with > another myserious parser function, and without running into performance issues. > Aha, so we're going to bloat the wikitext with way so complex template(s) to return the time diff in desired format instead? When I want the time difference, I want it in human legible format - "the difference is 1 year, 2 months, 3 days, 4 hours, 5 minutes and 6 seconds", not in a number of seconds or so. I also want to be able to format the result any possible way simply by adding the format string as a parameter of the function (such as {{#time:}} has now) without having to create and call either bunch of one-format-purpose templates or way so complex, very possibly nested, templates with dozens of {{#if:}}s and {{#switch:}}es and other stuff which actually would run into performance issues much earlier. Anyway, so far we don't have any #timeformat or any other function, right? So _after_ we'll have it, thus we'll be able to format the time differences easier than by dozens of {{#expr:}}s in dozens of (nested) templates, this request might be closed. We do not have any _simple_ way how to do what's requested.