{----------------------------------------------------- This algorithm is based on the Gauss formula for a date of Passover. When the Passover date is known for two consecutive years, it is possible to determine a length of the Hebrew year. When the length of Hebrew year is known (there are 6 options), it is possible to determine how many days does each month of the Hebrew year have (and is there Adar-2 inserted). (Heshvan, Kislew and Adar can have either 29 or 30 days.) When date of Passover is known for a given year and length of each month is known it is easy to calculate everything else. Sorry, it was originally in Russian for DOS, I tryed to translate most Russian input/output. The program was originally intended to convert hebrew dates in ancient manuscripts and tombstone inscriptions into Gregorian days, but it can be modified for other purposes, the important part is this Passover date calculation. Historians even today use tables, and there were rumors (for example see Gershom Sholem's book on Shabbetai Zvi), that the tables can have mistakes, because in some cases days of the week in manuscripts do not agree with what they have according to the table. I tested this program on many test examples, it worked well. Note that it works for the Gregorian calendar. In Russia before 1917 and in Europe before 1400s-1700s (different for each country) the Julian calendar was in use, which is different for leap years: 1900, 1800, 1700, (but not 2000 and 1600) 1500, 1400 are regular years in Gregorian but not in Julian!! - M.N. } program hebc (input, output); uses crt; var hy, pas, rh, gr, lgy, mm , dd, gdd, gmm, mc, dayh, dayg: integer; ch:char; gm: array[1..12] of integer; hm: array[1..13] of integer; mon: array[1..12] of string; monh:array[1..13] of string; week:array[0..6] of string; {----------------------------------------------------- } procedure inst; begin clrscr; textbackground(1); textcolor(14); for mc:=1 to 26 do writeln(' '); gotoxy(1,1); writeln(' Hebcal (c) 1995, M. Nosonovsky'); gotoxy(1,7); end; {----------------------------------------------------- Playing some music } procedure music; begin sound(523); delay(600); nosound; delay(230); sound(523); delay(600); nosound; delay(230); sound(659); delay(300); nosound; sound(554); delay(300); nosound; sound(523); delay(300); nosound; sound(659); delay(300); nosound; delay(230); sound(659); delay(600); nosound; delay(230); sound(784); delay(300); nosound; sound(698); delay(300); nosound; sound(659); delay(300); nosound; sound(698); delay(300); nosound; delay(230); sound(698); delay(600); nosound; delay(230); sound(831); delay(300); nosound; sound(784); delay(300); nosound; sound(698); delay(300); nosound; sound(659); delay(300); nosound; delay(230); sound(554); delay(300); nosound; sound(554); delay(300); nosound; sound(523); delay(600); nosound; end; {----------------------------------------------------- Initialization gm[12] number of days in the Gregorian months (by default February has 28 days) gh[13] number of days for Hebrew year, by default Heshwan=29, Kislev=30, Adar=29, Adar2=0. mon[12] names of Grigorian months monh[13] names of Hebrew months week[7] names of weekdays } procedure inic; begin gm[1] :=31; gm[2] :=28; gm[3] :=31; gm[4] :=30; gm[5] :=31; gm[6] :=30; gm[7] :=31; gm[8] :=31; gm[9] :=30; gm[10]:=31; gm[11]:=30; gm[12]:=31; hm[1] :=30; hm[2] :=29; hm[3] :=30; hm[4] :=29; hm[5] :=30; hm[6] :=29; hm[7] :=0; hm[8] :=30; hm[9] :=29; hm[10]:=30; hm[11]:=29; hm[12]:=30; hm[13] :=29; mon[1]:=' Jan'; mon[2]:=' Feb'; mon[3]:='Mar'; mon[4]:=' Aprš'; mon[5]:=' May '; mon[6]:=' Jun '; mon[7]:=' Jul'; mon[8]:=' Augš';mon[9]:='Sep '; mon[10]:=' Oct';mon[11]:='Nov ';mon[12]:=' Dec'; week[2]:=' Monday';week[3]:=' Tuesday'; week[4]:=' Wedensday'; week[5]:=' Thursday';week[6]:=' Fridayš'; week[0]:=' Saturday'; week[1]:=' Sunday'; monh[1]:=' Tishre';monh[2]:=' Heshvan';monh[3]:=' Kislev'; monh[4]:=' Tevet'; monh[5]:=' Shvat'; monh[6]:=' Adar'; monh[7]:=' Adar - 2'; monh[8]:=' Nisan'; monh[9]:=' Iyyar'; monh[10]:=' Sivan'; monh[11]:=' Tammuz'; monh[12]:=' Av'; monh[13]:=' Elul'; end; {----------------------------------------------------- Calculates day of week for given Gregorian year, month, day of months } function dw(yw, mw, dww :integer) :integer; var jj, ce, dod :integer; begin if mw<3 then begin yw:=yw-1; mw:=mw+12 end; ce:=yw div 100; jj:=yw mod 100; dod:=dww+(26*mw+26) div 10+jj+jj div 4 +ce div 4 -2*ce; dw:=dod mod 7 end; {-----------------------------------------------------} procedure ddd; forward; {-----------------------------------------------------} procedure prhy; var lhy, p1, p2: integer; {----------------------------------------------------- Calculates the date of Passover for a given Hebrew year } function passov (hyear :integer):integer; var c, mm, b, gy, cent, d, pass :integer; hy1, a, br, mmm, m : real; begin {Basically, it calculates astronomically the date of spring's full moon, then doing some adjustments, because the Passover can be only during certain days of the week.} hy1 := hyear; a := (12*hy1+17); a := 19*(a/19-trunc(a/19)); b := hyear mod 4; br := b; {Precision is very important here!!!) mmm := 32.0440933+1.5542418*a+0.25*br-0.00317779*hy; mm := trunc(mmm); m := mmm-mm; c := (mm+3*hyear+5*b+5) mod 7; case c of 0: if (a>11) and (m>0.63287037) then pass := mm+1 else pass := mm; 1: if (a>b) and (m>0.63287037) then pass := mm+2 else pass := mm; 2, 4, 6 : pass := mm+1; 3, 5 : pass := mm end; gy := hyear-3760; cent := gy div 100; d := cent - 2 - (cent div 4); passov := pass+d {this is only number of day in the Greg year, not day and month} {I belive this parameter d makes difference between Gregorian and Julian} end{of funtion passov}; {-----------------------------------------------------} begin{of prhy} p1:=passov(hy); p2:=passov(hy-1); rh:=p2+163; {length of Hebrew year is equal to a distance between two Passovers + length of Gregorian year} lhy:=p1-p2+lgy; {There are 6 possible options Depending on them some months will have different number of days} case lhy of 353: begin hm[2]:=29; hm[3]:=29; hm[6]:=29; hm[7]:=0 end; 354: begin hm[2]:=29; hm[3]:=30; hm[6]:=29; hm[7]:=0 end; 355: begin hm[2]:=30; hm[3]:=30; hm[6]:=29; hm[7]:=0 end; 383: begin hm[2]:=29; hm[3]:=29; hm[6]:=30; hm[7]:=29 end; 384: begin hm[2]:=29; hm[3]:=30; hm[6]:=30; hm[7]:=29 end; 385: begin hm[2]:=30; hm[3]:=30; hm[6]:=30; hm[7]:=29 end; else writeln(' error lhy=',lhy) end; end; {----------------------------------------------------- This is just i/o, ignore it it's in Russian} procedure dat; begin{of dat} gotoxy(1,8); writeln(' Ž…„…‹…ˆ… „€’›'); gotoxy(1,10); write(' ‚¢¥¤¨â¥ ¥¢à¥¿áª¨¿ £®¤: '); read(hy); repeat gotoxy(1,11); clreol; write(' ‚¢¥¤¨â¥ ¬¥áïæ (àãá᪨¬¨ ¡ãª¢š¬¨):'); ch:=readkey; case ch of '[','{','å','•' : mm:=2; 'r','R','Š','ª' : mm:=3; 'i','I','˜','è' : mm:=5; 'y','Y','','­' : mm:=8; 'b','B','ˆ','¨' : mm:=9; 'c','C','á','‘' : mm:=10; '"', chr(39),'í','' : mm:=13; else begin if (ch='n') or (ch='N') or (ch='â') or (ch='’') then begin write('’'); ch:=readkey; case ch of 'b','B','¨','ˆ' : mm:=1; 't','T','¥','…' : mm:=4; 'f','F','€','š' : mm:=11 end; end; if (ch='f') or (ch='F') or (ch='€') or (ch='š') then begin write('€'); ch:=readkey; if (ch='d') or (ch='D') or (ch='‚') or (ch='¢') then mm:=12; if (ch='l') or (ch='L') or (ch='¤') or (ch='„') then mm:=6; end; end end{ of case}; gotoxy(1,11); clreol; write(' ',monh[mm]); if mm=6 then begin write(' ( 1 / 2) ? '); ch:=readkey; if ch='2' then begin mm:=7; write(' š¤šà ¢â®à®¿'); end else write(' š¤šà ¯¥à¢ë¿'); end; writeln(' '); gotoxy(1,24); writeln('„«ï ¨§¬¥­¥­¨ï ¬¥áïæš ­š¦¬¨â¥ "Q", ¤«ï ¯à®¤®«¦¥­¨ï - «î¡ãî ª«š¢¨èã'); ch:=readkey; gotoxy(1,24); clreol; until (ch<>'q') and (ch<>'Q'); gotoxy(1,13); clreol; gotoxy(1,12); write(' ‚¢¥¤¨â¥ ¤¥­ì ¬¥áïæš:'); read(dd); ddd; prhy; ddd; writeln(' '); writeln(' '); writeln(' ',gdd,' ', mon[gmm],' ',gr, ' £®¤š, ', week[dw(gr,gmm,gdd)]); end; {-----------------------------------------------------} procedure ddd; begin {For a given hebrew year (hy) it calculates Greg. year (gr), length of Greg year (lgy) and modifies number of days for February} gr:=hy-3760; if ((gr mod 4)=0) and ((gr mod 100) <> 0) or (((gr div 100) mod 4) =0) and ((gr mod 100)=0) then begin lgy:=366; gm[2]:=29 end else begin lgy:=365; gm[2]:=28 end; dayh:=dd; {now, when everything is known it just uses the arrays gm, hm to calculate a gregorian date corresponding to the hebrew date} for mc:=1 to mm-1 do dayh:=dayh+hm[mc]; dayg:=dayh+rh-1; if dayg<307 then begin mc:=3; gr:=gr-1 end else begin dayg:=dayg-306; mc:=1 end; gdd:=dayg; repeat begin { write(' mc=',mc,' gdd=',gdd,' gm[mc]=',gm[mc]);} gdd:=gdd-gm[mc]; mc:=mc+1 end until gdd<=0; gmm:=mc-1; gdd:=gdd+gm[gmm]; { writeln(' year-',gr, ' month-', gmm,' day of month-', gdd);} end; {----------------------------------------------------- Some drawings on the screen and calculation of gregorian dates for some fixed hebrew dates, namely for holidays, for a given year just ignore it please!!! } procedure calen; begin gotoxy(1,6); write(' ‚¢¥¤¨â¥ £®¤ ®â ‘®â¢®à¥­¨ï Œ¨àš:'); read(hy); gr:=hy-3760; mm:=1; dd:=1; ddd; prhy; gotoxy(1,3); gr:=hy-3760; writeln('________________________________________________________________________________'); writeln(' Šš«¥­¤šàì ­š ',hy,' (',gr-1,'/',gr,') £®¤.'); writeln(' ______________________________________________'); mm:=1; dd:=1; ddd; writeln(' ®è ha-˜š­š ',gdd,mon[gmm]); dd:=10; ddd; writeln(' ‰®¬ Š¨¯¯ãà ',gdd,mon[gmm]); dd:=15; ddd; writeln(' ‘㪪®â ',gdd,mon[gmm]); dd:=23; ddd; writeln(' ‘¨¬åšâ ’®àš ',gdd,mon[gmm]); mm:=3;dd:=25; ddd; writeln(' •š­ãªš ',gdd,mon[gmm]); mm:=5;dd:=15; ddd; writeln(' ’ã ¡¨-˜¢šâ ',gdd,mon[gmm]); if hm[7]=0 then mm:=6 else mm:=7; dd:=14;ddd; writeln(' ãਬ ',gdd,mon[gmm]); mm:=8; dd:=15; ddd; writeln(' ¥ášå ',gdd,mon[gmm]); if hy>5707 then begin dd:=27; ddd; writeln(' „¥­ì Ššâšáâà®äë ',gdd,mon[gmm]) ; mm:=9; dd:=4; ddd; writeln(' „¥­ì ¥§š¢¨á¨¬®á⨠',gdd, mon[gmm]) end; mm:=9;dd:=18; ddd; writeln(' ‹š£ ¡š-Ž¬¥à ',gdd, mon[gmm]); mm:=10; dd:=6; ddd; writeln(' ˜š¢ã®â ',gdd, mon[gmm]); mm:=12; dd:=9; ddd; if dw(gr,gmm,gdd)=0 then if gdd<gm[gmm] then gdd:=gdd+1 else begin gmm:=gmm+1; gdd:=1 end; writeln(' „¥¢ï⮥ €¢š (¯®áâ) ',gdd, mon[gmm]); end; begin{ of programme} inst; inic; gotoxy(3,4); writeln(' à®£àš¬¬š HebCal ¬®¦¥â àš¡®âšâì ¢ ¤¢ãå ०¨¬šå: '); writeln(' ०¨¬ „€’€, â.¥. ¯¥à¥¢®¤ ¤šâë ¥¢à¥¿áª®£® ªš«¥­¤šàï ¢ ¤šâã '); writeln(' ¯® £à¨£®à¨š­áª®¬ã ªš«¥­¤šàî'); writeln(' ¨ ०¨¬ Š€‹…„€œ, â.¥. ®¯à¥¤¥«¥­¨¥ ¤šâ ®á­®¢­ëå ¯àš§¤­¨ª®¢'); writeln(' ¢ §š¤š­­®¬ £®¤ã.'); writeln(' '); music; repeat gotoxy(3,10); writeln(' ‚ë¡¥à¨â¥, ¯®¦š«ã¿áâš, ०¨¬ àš¡®âë ( „ / Š )'); ch:=readkey; for mc:=3 to 10 do begin gotoxy(1,mc); clreol; end; if (ch='k') or (ch='K') or (ch='ª') or (ch='r') or (ch='R') then calen else dat; gotoxy(40,23); write(' „«ï ¢ë室š ­š¦¬¨â¥ ª«š¢¨èã "Q"'); ch:=readkey; for mc:=3 to 25 do begin gotoxy(1,mc); clreol; end; until (ch='q')or(ch='Q')or(ch='¿')or(ch='‰'); clrscr; gotoxy(5,24); writeln(' „®¯®«­¨â¥«ì­šï ¨­ä®à¬šæ¨ï ® ¯à®£àš¬¬¥ ᮤ¥à¦¨âáï ¢ äš¿«¥ HEBCAL\readme'); music; end. ÿÿÿÿÿÿÿÿLet me know, if you find this useful.