HEJMO U8 | FR | EN

TAGNUMERILO

Tradukoj: chapelitaj Unikodoj (U8) | traduction fran├žaise (FR) | english translation (EN)

Se via TTT-legilo ne permesas JavaScript-on, vi ne povas nek vidi nek uzi la chisuban JavaScript-itan tagnumerilon:

Kial numeri tagojn?

Kiom da tagoj apartigas du kalendarajn datojn?

Kiu dato apartighas iom da tagojn de iu dato?

Tiaj simplaj demandoj shajnas malsimple respondeblaj, pro la tempokalkulaj sistemoj, t.e. kalendaroj, aspektas malmulte regulaj, esceptoplenaj. Tial kutimaj kalendaraj algoritmoj uzas abakojn por komputi de chiu dato la tagnumeron, law vicaj tagnumeroj, de kie la problemo reduktighas al simpla aritmetika diferenco inter du tagnumeroj.

Tiu artikolo prezentas senabakan tagnumeran algoritmon, kaj ties inverson (de tagnumero al dato), por la nuna okcidenta Gregoria kalendaro, aw ties pli simpla Julia antawanto ankoraw uzebla hodiaw se nur tra du jarcentoj. Char ambaw algoritmoj necesas nur simplan entjeran aritmetikon, kun nur entjeraj (senkomaj) nombroj kaj ewklidaj dividoj (t.e. kun entjeraj kvociento kaj resto), ili estas aparte tawgaj por simplaj komputrimedoj, kiaj permana komputado aw la plej malmultekostaj (kaj plej multnombraj) procesoretoj.

Kalendaraj faktoj

La terglobo rivoluas chirkaw sia polusa akso po unu tago relative al la suno, kaj chirkaw la suno po unu jaro relative al foraj steloj. La senshangha angulo inter la du rivoluaj aksoj kawzas la sezonojn, kun kiuj provas samfazi la tielnomataj "sunaj" kalendaroj, kiaj la Gregoria kaj Julia. Nuntempa astronomia mezuro de unu jaro egalas proksimume 365,2422 tagoj.

La Julian kalendaron enkondukis la romiana imperiestro Julio Cezaro en 45 a.K. konsilite de egiptaj astronomiistoj. Ghia jaro entenas 365 tagoj, dispartigitaj en la nunaj 12 monatoj, plus unu "supertago", aldonita la 29an de februaro chiu "superjaro" obla de kvar. Tiu alproksimigho de la jardawro, meznombre 365,25 tagoj, bonega relative al tiamaj astronomiaj iloj, tamen malfruigas la Julian kalendaron proksimume po 3 tagoj en chiu kvarcentjara periodo.

Post kvar tiaj periodoj, pro tro evidenta malfruo, la Gregorian kalendaron enkondukis katolika papo Gregorio la 13a en 1582. Li unue plibonigis l' alproksimighon de la jardawro, meznombre 365,2425 tagoj, per salto de la supertago de chiu jaro obla de cent sed ne de kvarcent, t.e. de tri supertagoj en chiu kvarcentjara periodo, kaj due refazigis la kalendaron per salto de 10 tagoj: la morgawo de jawdo 1582-10-04 estis vendredo 1582-10-15.

La shanghon, de la Julia kalendaro al la Gregoria, ne tuj akceptis chiuj landoj: unuaj estis la katolikaj (ekz. Francio ekde lundo 1582-12-20), pli poste la protestantaj (ekz. Anglio ekde jawdo 1752-08-14), kaj ech pli poste la ortodoksaj (ekz. Rusio ekde jawdo 1918-02-14).

Senabaka entjer-aritmetika algoritmo

Unue ni elektu la 1an de Marto kiel komenco de la jara periodo (kaj do numeru januaro=13 kaj februaro=14): al ties fino tiel foriras la okazebla supertago. Plie, aperas kvinmonata periodo de 31+30+31+30+31 = 153 tagoj:
monato (m): 3 4 5 6 7 8 9101112 1314
nombro da tagoj: 313031303131303130313128
periodo: 153 153
(((m+1)*153)/5)-122 0316192122153184214245275306337

Iom da atento, al la vicaj obloj de 153/5 kaj al ghiaj diferencoj, facile aperigas la formulon de la kvara tabulolinio, kiu egalas la sumon de la nombroj da tagoj de la monatoj inter la 1a de marto kaj la 1a de monato "m"; aldonu la monatan tagnumeron de la dato por obteni la nombron de tagoj inter la 1a de marto kaj tiu dato.

Inter la 1a de marto de iu baza superjaro (obla de 400 por la Gregoria kalendaro, aw de 4 por la Julia), kaj la 1a de marto de la "j"a posta jaro, la nombro da tagoj estas (j*365)+(j/4)-(j/100)+(j/400) por la Gregoria kalendaro (aw pli simple (j*365)+(j/4) por la Julia).

Do jen estas la tagnumera algoritmo, kun J=jaro M=monato T=tago, kaj NG aw NJ = tagnumero law la Gregoria aw Julia kalendaro:

Por malkovri la datan semajnotagon, dividu N en semajnaj periodoj po 7 tagoj (rimarkinde la Gregoria kvarcentjara periodo de 146097 tagoj estas oblo de 7); la resto de la ewklida divido egalas:
resto: 0123456
Julia (B=0): lunmarmerjawvensabdim
Gregoria: merjawvensabdimlunmar

Ekzemple: 2005-09-03, J=2005 M=9 T=3, j=5 m=9, NJ=NG=2012=7*287+3=sabato.

Inversa algoritmo

La tagnumeron NG unue dividu en kvarcentjaraj periodoj po 146097 tagoj: NG=146097*K+R (t.e. K kaj R estas la kvociento kaj resto de la ewklida divido NG/146097). Se R=146096, la dato estas la lasta supertago de la kvarcentjara periodo, la 29a de februaro de la jaro J=B+K*400+400.

Alie due dividu R en centjaraj periodoj po 36524 tagoj: R=36524*C+c. La antawaj du unuaj pashoj necesas nur por la Gregoria kalendaro; por la Julia, startu chi tie kun c=NJ.

Trie dividu c en kvarjaraj periodoj po 1461 tagoj: c=1461*k+r. Se r=1460, la dato estas supertago, la 29a de februaro de la jaro J=B+K*400+C*100+k*4+4.

Alie kvare dividu r en jaraj periodoj po 365 tagoj: r=365*i+t, kaj kalkulu j=B+K*400+C*100+k*4+i, kaj m=(((t+31)*5)/153)+2, kaj T=t-(((m+1)*153)/5)+123.

Fine, se m>12, kalkulu J=j+1 kaj M=m-12, alie J=j kaj M=m. La dato estas J=jaro M=monato T=tago.

Ekzemple: NJ=2012, k=1 r=551, i=1 t=186, j=2005 m=9 T=3, J=2005 M=9, 2005-09-03.

Uzoj de la Julia algoritmo

Unue, 16 ghis 19 jarcentoj de historio estis datitaj law la Julia kalendaro. Ekzemple, dum la vivo de Zamenhof, rusoj ankoraw uzis la Julian kalendaron (ghis ghia merkredo la 31a de januaro 1918, kiu estis la Gregoria 13a de februaro), tiam 13 tagojn pli malfrua ol la Gregoria, uzata de okcidentanoj jam de tri jarcentoj.

Due, procesoretoj malpli koste kalkulas per 16 bitaj nombroj, inter 0 kaj 65535, t.e. la nombro da tagoj de proksimume 180 jaroj. Char inter 1900-03-01 kaj 2100-02-28 la Gregoriaj kaj Juliaj superjaroj egalas, la pli simplan Julian algoritmon oni povas uzi kun ekzemple 1900 kiel baza jaro (1900-03-01 = tagnumero 0, ghis tagnumero 65535 = 2079-05-05).

Kodfontoj

En JavaScript:
vidu en la HTML-a fontkodo de chi tiu pagho.
En C lingvajho:
static int gregoria = 1; // 1:Gregoria 0:Julia
typedef struct{int tago, monato, jaro;} dato; // 1..31, 1..12, ..2005..
int tagnumero(dato d) { // konvertu daton en tagnumeron
  if(monato<3){ d.jaro-=1; d.monato+=12; } // jarkomencu 1an de marto
  return d.jaro*365 + d.jaro/4 + (gregoria ? -d.jaro/100 + d.jaro/400 : 0)
       + (d.monato+1)*153/5-123 + d.tago;
}
int semajntago(int n) { // konvertu tagnumeron en:
  return (gregoria ? n+2 : n) % 7; // 0=lundo .. 6=dimancho
}  
void tagdato(int n, dato *d) { // konvertu tagnumeron en daton
  int m, j=0;
  if(gregoria) {
    m = n/146097;  j += m*400;  n -= m*146097; // 400-jaraj periodoj
    if(n==146096) { d->jaro=j+400; d->monato=2; d->tago=29; return; }
    m = n/36524;   j += m*100;  n -= m*36524;  // 100-jaraj periodoj
  }
  m = n/1461;  j += m*4;  n -= m*1461; // 4-jaraj periodoj
  if(n==1460) { d->jaro=a+4; d->monato=2; d->tago=29; return; }
  m = n/365;   j += m;    n -= m*365;  // 1-jara periodoj
  m = (n+31)*5/153+2;     n -= (m+1)*153/5-123;
  if(m>12) { j+=1; m-=12; } // jarkomencu 1an de januaro
  d->jaro=j; d->monato=m; d->tago=n; return;
}
En Forth :
1 value gregoria  \ 1:Gregoria 0:Julia
: dato>  \ t m j -- n ; konvertu daton t/m/j en tagnumeron n
  >r  dup 3 < IF 12 + r> 1- >r THEN  \ jarkomencu 1an de marto
  1+ 153 * 5 / 123 -  +  \ -- n | j ; n tagoj de 1/3/j al t/m/j
  r@ 4 / +  gregoria IF r@ 100 / - r@ 400 / + THEN  r> 365 * +
;
: >semajntago  \ n -- s ; konvertu tagnumeron en:
  gregoria IF 2 + THEN  7 mod  \ 0:lundo .. 6:dimancho
;
: >dato  \ n -- t m j ; konvertu tagnumeron n en daton t/m/j
  0 >r  gregoria IF
    146097 /mod 400 * r> + >r  \ 400-jaraj periodoj
    146096 over = IF drop 29 2 r> 400 + exit THEN
    36524  /mod 100 * r> + >r  \ 100-jaraj periodoj
  THEN  \ -- n | j
  1461 /mod 4 * r> + >r  \ 4-jaraj periodoj
  1460 over = IF drop 29 2 r> 4 + exit THEN
  365  /mod     r> + >r  \ 1-jara periodoj
  dup 31 + 5 * 153 / 2 +  tuck 1+ 153 * 5 / 123 - - swap  \ -- t m | j
  dup 12 > IF 12 - r> 1+ >r THEN  r>  \ -- t m j
;

Ligoj

CL20080702