Template talk:Ordinal date

Latest comment: 17 years ago by Verdy P in topic testing

Old discussions

edit
These issues are resolved

Expression replacement possibility

edit

{{#expr: {{ #switch: {{CURRENTMONTH}}|01=0|02=31|03=59|04=90|05=120|06=151|07=181|08=212|09=243|10=273|11=304|12=334}} + {{CURRENTDAY}} }}

  • 310
Does MediaWiki support switch? --Uncle Ed 15:50, 19 April 2006 (UTC)Reply
Yes, see above. This code can also be used with noinclude subst magic to timestamp the ordinal. — xaosflux Talk 02:33, 20 April 2006 (UTC)Reply
Implemented, please report any problems. — xaosflux Talk 23:30, 23 April 2006 (UTC)Reply

Leap year

edit

The day after February 29, 2008 this template will have a one off error. Perhaps we could fix this now, by incorporating a template like {{isLeapYear}}. --Uncle Ed 14:58, 27 April 2006 (UTC)Reply

// Add one for leap year dates between March and December
If (isLeapYear && currentMonth > 2) result++


The above is some pseudocode that might fix the leap year problem.

Proposed fix

edit

Expression which adds 1 for dates between March 1st and December 31st during leap years:

{{#expr: {{isLeapYear}} * {{#switch: {{CURRENTMONTH}} | 1=0 | 2=0 | 1}} }}
  • assume it's a leap year and month is May: expr = 1
  • assume it's a leap year and month is Feb: expr = 0
  • assume it's a not leap year and month is {{current month}}: expr = 0

Code shrinking

edit

I've replaced the {{#switch: {{CURRENTMONTH}} | 1=0 | 2=0 | 1}} code with {{ #expr: {{CURRENTMONTH}}>2 }} as it involves less computations. — xaosflux Talk 17:51, 29 April 2006 (UTC)Reply

These should always equal

edit
  • CURRENT: 1 - 1
  • 1: 0 - 0
  • 2: 0 - 0
  • 3: 1 - 1[not necessary]
  • 4: 1 - 1

rv new code base

edit

Old version:

{{#expr: {{ #switch: {{CURRENTMONTH}}|01=0|02=31|03=59|04=90|05=120|06=151|07=181|08=212|09=243|10=273|11=304|12=334}} + {{CURRENTDAY}} + ( {{isLeapYear}} * {{ #expr: {{CURRENTMONTH}}>2 }} ) }}


Updated version:

{{#expr: (({{CURRENTYEAR}}+({{CURRENTMONTH}}+9)/12-0.5 round 0)*1461/4-0.5 round 0)- (({{CURRENTYEAR}}+({{CURRENTMONTH}}+9)/12-0.5 round 0)/100-0.5 round 0)+ (({{CURRENTYEAR}}+({{CURRENTMONTH}}+9)/12-0.5 round 0)/400-0.5 round 0)-( (({{CURRENTYEAR}}+10/12-0.5 round 0)*1461/4-0.5 round 0)- (({{CURRENTYEAR}}+10/12-0.5 round 0)/100-0.5 round 0)+ (({{CURRENTYEAR}}+10/12-0.5 round 0)/400-0.5 round 0))+ ((({{CURRENTMONTH}}+9)mod 12+4)*153/5-0.5 round 0)- ((10+4)*153/5-0.5 round 0)+ {{CURRENTDAY}}}}


These both produce the same results right now:

311=310

I may be missing something, but the new version seems to be performing many more server side calculations everytime this template is invoked. Also what is the base algorithim that is being used here? And does it account for leap years? The old version worked on the premise that the number of days per month is a static value, and offset leapyears with a test. — xaosflux Talk 00:46, 27 May 2006 (UTC)Reply

The algorithm is wellknown. It uses a single formula based on the 153 days cycle every 5 months. The apparent computing complex is not an issue, but using an external template has a severe cost on the server. My formula is proven for the Gregorian calendar, and part of many libraries. verdy_p 18:15, 8 November 2006 (UTC)Reply

Math Error?

edit

CURRENT CODE {{#expr: {{CURRENTDAY}}+{{#switch: {{CURRENTMONTH}}|1=0|2=31|3=59+{{IsLeapYear}}|4=90|5=120|6=151|7=181|8=212|9=243|10=273|11=304|12=334}}}}

CURRENTDAY is always equal to the current day of the current month: 6 CURRENTMONTH is always equal to a number from 1-12 corresponding with the current month: 11 The table:

  • 1=0
  • 2=31
  • 3=59
  • 4=90
  • 5=120
  • 6=151
  • 7=181
  • 8=212
  • 9=243
  • 10=273
  • 11=304
  • 12=334

Is the number of days that are in all of the months preceeding the CURRENTMONTH in a NON-leap year. This number is static as those months always have the same number of days in them, and are cumulative:

  • Jan=31 days
  • Feb=28 days
  • Mar=31 days
  • Apr=30 days
  • May=31 days
  • etc.
The table above is from
  • 2|31 (number of days in month 1)
  • 3|{31 (number of days in month 1)} + {28 (number of days in month2)}=59
  • 4|{31 (number of days in month 1)} + {28 (number of days in month2)} + {31 (number of days in month3)} = 90
  • 5|{31 (number of days in month 1)} + {28 (number of days in month2)} + {31 (number of days in month3)} + {30 (number of days in month4)} = 120
  • {{IsLeapYear}} is equal to 0 if it is NOT a leap year, and 1 if it is a leap year.

During a leap year, the ordinal day must be offset for all days after Feb29'th in the calculation formula. The formula above is adding this to the month of march, but then reverting to the lookup table only in April.

The last set of what I see as working code took care of this calculation by adding 1 day to all months that were greater than February, during a leap year, by way of the prior code.

In other words I screwed up, see below, it's now minimally "better" evaluating {{IsLeapYear}} only for 10 out of 12 months. -- Omniplex 00:30, 2 June 2006 (UTC)Reply

Edit conflict

edit
The old version was fine, I've minimally trimmed it, one expr containing one switch containing one {{IsLeapYear}} can handle all years. -- Omniplex 23:26, 1 June 2006 (UTC)Reply
Made a partial revert from this:
{{#expr: {{CURRENTDAY}}+{{#switch: {{CURRENTMONTH}}|1=0|2=31|3=59+{{IsLeapYear}}|4=90|5=120|6=151|7=181|8=212|9=243|10=273|11=304|12=334}}}}
Back to using a leap year adding function, please correct me if I'm mistaken, but that formula looks like it would only add +1 during march, then the ordinal dates would be off by one once april came around during leap years. Initial testing looks like the #switch is ignoring the leading zeros, as they are not escaped with "'s, as confirmed in the documentation. — xaosflux Talk 23:42, 1 June 2006 (UTC)Reply
Striking my nonsense remark above, of course. Maybe we should add optional parameters 1=yyyy, 2=mm, 3=dd, defaults current date, for more flexibility (?) -- Omniplex 00:11, 2 June 2006 (UTC)Reply
I've added "month", "day", and "year" parameters so that this template can be used in other templates (I'm using it for User:Alerante/ddate). æle  2006-06-02t01:49z

Code verifications

edit

The TEMPLATE figure should always match the MANUAL figures below.

DD-MMM-YYYY Manual Template
01-JAN-1900 1 1
01-FEB-1900 32 32
28-FEB-1900 59 59
01-MAR-1900 60 60
01-APR-1900 91 91
31-DEC-1900 365 365
DD-MMM-YYYY Manual Template
01-JAN-2000 1 1
01-FEB-2000 32 32
28-FEB-2000 59 59
29-FEB-2000 60 60
01-MAR-2000 61 61
01-APR-2000 92 92
31-DEC-2000 366 366
DD-MMM-YYYY Manual Template
01-JAN-2007 1 1
01-FEB-2007 32 32
28-FEB-2007 59 59
01-MAR-2007 60 60
01-APR-2007 91 91
31-DEC-2007 365 365
DD-MMM-YYYY Manual Template
01-JAN-2008 1 1
01-FEB-2008 32 32
28-FEB-2008 59 59
29-FEB-2008 60 60
01-MAR-2008 61 61
01-APR-2008 92 92
31-DEC-2008 366 366
Okay, but why is it limited to common era? Patrick apparently found a leap year formula working always for Template:YMD2MJD (edit · talk · links · history) at Meta. Checking Locke's formula:
{{ordinal date|year=400|month=3|day=1}} = 61
{{ordinal date|year=100|month=3|day=1}} = 60
{{ordinal date|year=+4|month=3|day=1}} = 61
{{ordinal date|year=-0|month=3|day=1}} = 61
(Note that astronomical year 0 is year 1 BC in proleptic Julian and Gregorian calendars; note that at this time, leap years were computed inaccurately using the Roman calendar, incorrectly thought to be the Julian calendar. So interpret the result only in the astronomical calendar, or in the Gregorian proleptic calendar for 1 BC; even the Julian calendar was applied in errors at that time, after Julius Caesar death, until the emperor Augustus fixed it again by progressively restoring the Julian calendar up to 12 AD!)
{{ordinal date|year=-4|month=3|day=1}} = 61
{{ordinal date|year=-100|month=3|day=1}} = 60
{{ordinal date|year=-400|month=3|day=1}} = 61
Perfect, it's proleptic Gregorian, not CE. -- Omniplex 05:38, 2 June 2006 (UTC)Reply
This has been fixed, using the single formula (without the call to the costly subtemplate and without any tests)

Looks like it may work, didn't test it that well :) Wait a second, were leap years even used BCE? — xaosflux Talk 05:48, 2 June 2006 (UTC)Reply

Not really before about 45BC, but "proleptic", pretending that the Julian calendar was always used. Or in astronomical dates (year + day number), where they apparently use a formula of one year = 365.25 days (that's Julian, not Gregorian) for historic years. Of course Locke's template is for real dates in a Gregorian calendar, not for astronomy. In Template:YMD2MJD (edit · talk · links · history) at Meta we managed to mix both calendars, good enough for a template, if you don't take it too seriously for historic dates. -- Omniplex 05:04, 15 June 2006 (UTC)Reply
All those discusions come from the revert of the formula used above and replaced by a switch. The formula using modular arithmetic only was OK for the whole proleptic Gregorian, including the pre-christian era starting in -4800 (4801 BC).
Who reverted the code and attempted to create the same thing using a costly subtemplate for leap year correction?
My formula was OK and proven! verdy_p 18:21, 8 November 2006 (UTC)Reply

testing

edit

311

311

Using the single formula, it works with subst, and does not use costly sub-templates (remember: subtempaltes are MORE costly for the server than #expr formulas which are very fast:

{{#expr:
 (((({{{year|{{CURRENTYEAR}}}}})*12+({{{month|{{CURRENTMONTH}}}}})+57608.5 round 0)/12-1.5 round 0)*1461/4-0.5 round 0)
-(((({{{year|{{CURRENTYEAR}}}}})*12+57609.5 round 0)/12-1.5 round 0)*1461/4-0.5 round 0)
-(((({{{year|{{CURRENTYEAR}}}}})*12+({{{month|{{CURRENTMONTH}}}}})+57608.5 round 0)/12-1.5 round 0)/100-0.5 round 0)
+(((({{{year|{{CURRENTYEAR}}}}})*12+57609.5 round 0)/12-1.5 round 0)/100-0.5 round 0)
+(((({{{year|{{CURRENTYEAR}}}}})*12+({{{month|{{CURRENTMONTH}}}}})+57608.5 round 0)/12-1.5 round 0)/400-0.5 round 0)
-(((({{{year|{{CURRENTYEAR}}}}})*12+57609.5 round 0)/12-1.5 round 0)/400-0.5 round 0)
+(((({{{month|{{CURRENTMONTH}}}}})+57608.5 round 0)mod 12+4)*153/5-0.5 round 0)
-428
+({{{day|{{CURRENTDAY}}}}})
}}

Result after subst: 311

And look above: it works with BC years too, starting on January 1, 4801 BC (i.e. -4800 using the proleptic Gregorian calendar, with astronomical year numbering)!
And note that it's not because you don't understand a modular arithmetic formula that it is wrong. The formula is exact and proven according to the astronomical definitions of the Gregorian calendar. The principles in this formula is to compute dates based on years starting in March; years are in a 1461 days cycle every 4 years; months are computed according to the 153 days cycle every 5 months. For more information about how it works, look at Julian day. (For higher precision, including far years, the formula is now based on the most recent and precise formula in Template:JULIANDAY.
The formula is directly equivalent to {{JULIANDAY|year|month|day}}-{{JULIANDAY|year|1|0}}, and slightly optimized where there are constants and terms of the difference are arranged by type.
Note also that the 0.5 adjustments in the formula are only needed for correct truncation of integers usign the round operator (because of its mathematical limitations for cyclic moular arithmetic). Unfortunately, there's no #expr operator that supports the true modulo and div operators for modular artithmetic (which is the arithmetic system used in all calendar and astronomical cyclic calculations).

verdy_p 18:38, 8 November 2006 (UTC)Reply


  • 1
  • 59
  • 275
  • 366
  • 1
  • 59
  • 274
  • 365
  • 1
  • 59
  • 274
  • 365