最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

wikitext - Regex or wikicode to find out if a date is more than 3 weeks old - Stack Overflow

programmeradmin3浏览0评论

I'm trying to create a template on Wikipedia in French that changes the category of a page three weeks after the date it was added.

There will be a date parameter, probably in the form DD/MM/YYYY, and we can find out the current date using the magic words {{LOCALDAY2}}/{{LOCALMONTH2}}/{{LOCALYEAR}}.

The problem is to find out whether the current date is 21 days older than the date on which the template was added.

It's easy if the two dates are in the same month, but more complicated if they are in different months, and even more so in different years.

Does anyone have a simple idea using wikicode or a regex?

Here is my current solution using {{LOCALWEEK}} which gives the number of the current week (semaine is the parameter containing the number of the week that the model was added), but I would prefer a ‘normal’ date:

{{#ifexpr: {{LOCALWEEK}} > {{#ifexpr: {{{semaine|0}}}>48 and {{LOCALWEEK}}<48 <!-- checks if added in December -->
                             | {{{semaine}}}-52 <!-- if in december, substracts 52 weeks -->
                             | {{{semaine}}}    <!-- if not, uses the current week number -->
                           }} + 3               <!-- adds 3 weeks to the week the template was added -->
   | [[:Catégorie:1]]                           <!-- if current week is less than 'semaine' + 3 -->
   | [[:Catégorie:2]]                           <!-- if current week is more than 'semaine' + 3 -->
}}

I'm trying to create a template on Wikipedia in French that changes the category of a page three weeks after the date it was added.

There will be a date parameter, probably in the form DD/MM/YYYY, and we can find out the current date using the magic words {{LOCALDAY2}}/{{LOCALMONTH2}}/{{LOCALYEAR}}.

The problem is to find out whether the current date is 21 days older than the date on which the template was added.

It's easy if the two dates are in the same month, but more complicated if they are in different months, and even more so in different years.

Does anyone have a simple idea using wikicode or a regex?

Here is my current solution using {{LOCALWEEK}} which gives the number of the current week (semaine is the parameter containing the number of the week that the model was added), but I would prefer a ‘normal’ date:

{{#ifexpr: {{LOCALWEEK}} > {{#ifexpr: {{{semaine|0}}}>48 and {{LOCALWEEK}}<48 <!-- checks if added in December -->
                             | {{{semaine}}}-52 <!-- if in december, substracts 52 weeks -->
                             | {{{semaine}}}    <!-- if not, uses the current week number -->
                           }} + 3               <!-- adds 3 weeks to the week the template was added -->
   | [[:Catégorie:1]]                           <!-- if current week is less than 'semaine' + 3 -->
   | [[:Catégorie:2]]                           <!-- if current week is more than 'semaine' + 3 -->
}}
Share Improve this question edited Mar 19 at 13:04 InSync 11.1k4 gold badges18 silver badges56 bronze badges asked Mar 19 at 13:00 oli_vi_eroli_vi_er 3401 silver badge10 bronze badges 2
  • 1 Regular expressions are not the best tool to do date comparisons. – Tim Biegeleisen Commented Mar 19 at 13:08
  • @TimBiegeleisen I know, but there are not many options on Wikipedia, unless making a module, but I'm really not good enough in lua. – oli_vi_er Commented Mar 19 at 17:05
Add a comment  | 

2 Answers 2

Reset to default 3

This is trivial with {{#time}}:

{{#ifexpr:
    {{#time:U}} - {{#time:U|{{{added}}}}} > 3 * 7 * 24 * 60 * 60
|[[:Catégorie:1]]
|[[:Catégorie:2]]
}}

U specifies that {{#time}} should output an Unix timestamp. {{#time:U}} is thus the "current" time, while {{#time:U|{{{added}}}}} marks the moment the template was added. The expression on the right-hand side is just the number of seconds in three weeks.

One common pitfall is that the page might need to be purged. Otherwise, MediaWiki may just load the page from cache without rerendering, causing the categories to not be updated.

Ahoy!

I found a cool way to find the difference between two dates without using any external date libraries. It is a math formula that should work in any language. I found the formula here

Difference between two dates using only math

Basically the formula is this...

dateValue = 365*year + year/4 - year/100 + year/400 + (153*month - 457)/5 + day - 306

There is an explanation on the original page as to how exactly the formula works. Basically some computations using the Gregorian calendar to ensure the correct amount of days in a month, taking into account leap years. In my limited testing it seems to work, which is excellent because that makes it language independent requiring no additional libraries.

Here is some proof of concept code in Perl. Basically take the DD/MM/YYYY date from the input, separate the date into individual day month year values. Take those separate values, plug them into the formula to generate a value for each date. Subtract these two values and take the ceiling of the result to get the difference of the two dates in days. Excellent and tidy solution.

Here is the code.

#!/usr/bin/perl -w
use POSIX; #to use the ceiling function

#dates are in DD/MM/YYYY
my @startingDates = ("20/03/2025", "10/04/2025", "01/01/2025", "01/06/2025" , "01/07/2025" , "01/08/2025" ,"01/09/2025");
my @endingDates   = ("10/04/2025", "29/04/2025", "30/01/2025", "01/06/2024" , "01/09/2025" , "11/09/2025" ,"01/09/2020");

for(0 ..  $#startingDates){ #make sure starting and ending arrays are the same size
  my $differenceInDays = &dateDiff($startingDates[$_],$endingDates[$_]);
  print "$startingDates[$_] $endingDates[$_] difference of $differenceInDays days\n";
}

sub dateDiff{
  my ($d1, $d2) = (shift, shift);

  #split into array where index (0,1,2) is (day,month,year)
  my @d1 =  split(/\//,$d1);
  my @d2 =  split(/\//,$d2);

  #DEBUG: print "@d1\n@d2\n";

  my (%d1, %d2);
  my @keys = ("d","m","y");

  @d1{@keys} = @d1;
  @d2{@keys} = @d2;

  #cool date difference math formula with no external libraries
  #365*year + year/4 - year/100 + year/400 + (153*month - 457)/5 + day - 306

  #DEBUG: for(keys %d1){ print "$_ $d1{$_}\n";  }

  my ($v1,$v2, $diff);
  $v1 = (365*$d1{"y"}) + $d1{"y"}/4 - ($d1{"y"}/100) + ($d1{"y"}/400) + ((153*$d1{"m"}) - 457)/5 + $d1{"d"} - 306;
  $v2 = (365*$d2{"y"}) + $d2{"y"}/4 - ($d2{"y"}/100) + ($d2{"y"}/400) + ((153*$d2{"m"}) - 457)/5 + $d2{"d"} - 306;
  $diff = abs($v2 - $v1); #absolute value to avoid negative numbers

  #DEBUG: print "v1=$v1 v2=$v2 difference=$diff\n";
  return ceil($diff);   #POSIX ceiling function: for the resulting decimal number
                         #take the ceiling to get the correct amount of days difference
}

Output looks like this...

$ perl date.difference.pl
20/03/2025 10/04/2025 difference of 21 days
10/04/2025 29/04/2025 difference of 19 days
01/01/2025 30/01/2025 difference of 29 days
01/06/2025 01/06/2024 difference of 366 days
01/07/2025 01/09/2025 difference of 62 days
01/08/2025 11/09/2025 difference of 41 days
01/09/2025 01/09/2020 difference of 1827 days

Im not sure what language wikicode uses, but this should work in any language. Just separate the date into individual day month year values, plug it into the formula, and subtract the two resulting values for the date difference.

Good Luck!

发布评论

评论列表(0)

  1. 暂无评论