HEJMO
U8
| FR
| EN
| |
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:
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.
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).
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:
Kalendaraj faktoj
Senabaka entjer-aritmetika algoritmo
monato (m): | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
nombro da tagoj: | 31 | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 | 31 | 28 |
periodo: | 153 | 153 | ||||||||||
(((m+1)*153)/5)-122 | 0 | 31 | 61 | 92 | 122 | 153 | 184 | 214 | 245 | 275 | 306 | 337 |
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: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Julia (B=0): | lun | mar | mer | jaw | ven | sab | dim |
Gregoria: | mer | jaw | ven | sab | dim | lun | mar |
Ekzemple: 2005-09-03, J=2005 M=9 T=3, j=5 m=9, NJ=NG=2012=7*287+3=sabato.
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.
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).
Inversa algoritmo
Uzoj de la Julia algoritmo
Kodfontoj
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;
}
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