{$I version.pas} {$IFNDEF DELPHI} {$M 64000, $1000, $1000} {$ENDIF} program HEBCLNDR { Passover, and other Hebrew Calendar work ; see procedure Help TurboPascal 7, Delphi 3, etc. } ; uses {$IFDEF DELPHI} SysUtils, {$ELSE} Dos, {$ENDIF} DateProx ; { 1 day (-0600..+1800) = 24 hours of 1080 parts each ; 25920 parts per day. First Month starts 02d 05h 204p Every Month length 29d 12h 793p ~ 235 Months are 19 Years } type HebrYr = 1..5879542 { Max HY for MJD in MJDate = longint } ; const MJD_AM1 = -2052003 ; Three761 = 3761 ; function HYtoMJD(const Y : HebrYr) : MJDate ; { based on E G Richards, Algorithm G, Hebrew Year Start (1 Tishri) to JDN with input from Remy Landau, http://www.geocities.com/Athens/1584/ OK by L E Doggett in http://charon.nmsu.edu/~lhuber/leaphist.html } const hpd = 24 { hours per day } ; pph = 1080 { parts per hour } ; var m { months from AM 1/1/1 }, tm { minor contribution from parts }, th { hours from hours & parts }, d { days }, t_ { parts of day } : longint ; w { DoW Sun=1 .. Sat=7 } : word ; E { This Year Leap }, E_ { Last Year Leap } : boolean ; begin {a } m := (235*Y - 234) div 19 ; {b'} tm := 204 + 793*(m mod pph) ; {c } th := 5 + 12*m + tm div pph + 793*(m div pph) ; {d } d := 1 + 29*m + th div hpd ; {e } t_ := (tm mod pph) + pph*(th mod hpd) ; { (d, t_) is Molod in Days & Parts from Hebrew time origin } {4 } w := Succ(d mod 7) ; {5 } E := ((7*Y + 13) mod 19) >= 12 ; { Whatever Y is, these } {6 } E_ := ((7*Y + 6) mod 19) >= 12 ; { cannot both give TRUE } {7 } if (t_ >= 18*pph) { DMZ } {} or ((t_ >= 9*pph + 204) and (w=3) and not E) { DGTR } {} or ((t_ >= 15*pph + 589) and (w=2) {and (not E)} and E_) { DB'T } {} then Inc(d) ; {8 } if Succ(d mod 7) in [1, 4, 6] then Inc(d) ; { DADU } HYtoMJD := d + (347997-2400001) { d + 347997 is EGR's answer } ; end {HYtoMJD} ; procedure HebDPtoGregYMDP(var d, p : longint ; var GY : integer ; var GM, GD : byte) ; begin Dec(p, 6*1080) ; if p < 0 then begin Dec(d) ; Inc(p, 24*1080) end ; MJDtoYMD(d{-2052004}+MJD_AM1-1, GY, GM, GD) ; end {HebDPtoGregYMDP} ; function HYtoHebrewMonth(const Y : HebrYr) : longint ; { was part of HYtoMJD ; see that for comment } begin {a } HYtoHebrewMonth := (235*Y - 234) div 19 ; end {HYtoHebrewMonth} ; procedure HebMonthtoMolodDP(m : longint ; var d, t_ : longint) ; { was part of HYtoMJD ; see that for comment } const hpd = 24 ; pph = 1080 ; var tm, th : longint ; begin {b'} tm := 204 + 793*(m mod pph) ; {c } th := 5 + 12*m + tm div pph + 793*(m div pph) ; {d } d := 1 + 29*m + th div hpd ; {e } t_ := (tm mod pph) + pph*(th mod hpd) ; end {HebMonthtoMolodDP} ; procedure HYtoMolodDP(const Y : HebrYr ; var d, t_ : longint) ; { as part of HYtoMJD ; see that for comment } const hpd = 24 ; pph = 1080 ; var m, tm, th : longint ; begin {a } m := (235*Y - 234) div 19 ; {b'} tm := 204 + 793*(m mod pph) ; {c } th := 5 + 12*m + tm div pph + 793*(m div pph) ; {d } d := 1 + 29*m + th div hpd ; {e } t_ := (tm mod pph) + pph*(th mod hpd) ; end {HYtoMolodDP} ; function MJDtoHY(const MJD : MJDate) : HebrYr ; var HY, X : longint ; {Z : integer ;} begin { firstly use X to approximate well; then shift if needed } X := MJD{+2052003}-MJD_AM1 ; HY := Succ(X div 365 - X div (1480*365)) ; { Z := 0 ; } while HYtoMJD(HY) > MJD do begin Dec(HY) ; { Dec(Z) } end ; while HYtoMJD(HY+1) <= MJD do begin Inc(HY) ; { Inc(Z) } end ; { Write(Z:5) ; } MJDtoHY := HY end {MJDtoHY} ; procedure InverseCheck ; var HY, X, Y : HebrYr ; MJD : MJDate ; const Cap = ' HY MJD HY HY-' ; begin Writeln(' Inverse Check:'^M^J, Cap) ; for HY := 2 to 9999 do begin Write(HY:8) ; MJD := HYtoMJD(HY) ; Write(MJD:12) ; X := MJDtoHY(MJD) ; Write(X:8) ; Y := MJDtoHY(MJD-1) ; Write(Y:8) ; if (X<>HY) or (Y+1<>HY) then Readln ; Write(^M) end ; Writeln('':50) ; end {InverseCheck} ; function CompareDiff(const A, B : MJDate) : shortint ; var C : longint ; begin C := A-B ; if C<0 then begin Write(' < ') ; CompareDiff := -1 end else if C>0 then begin write(' >') ; CompareDiff := +1 end else begin write(' = ') ; CompareDiff := 0 end ; end {CompareDiff} ; procedure CompareHeader ; begin Writeln(' GYear GY MJD1 GE MJD JE MJD ', 'HebYr? HY+MJD1 15Nisan DoW G:P J:P') end {CompareHeader} ; procedure CompareGregAndJulnEasterWithPesach(const GYS, GYE : integer) ; var MJD, GEMJD, JEMJD : MJDate ; HY : HebrYr ; GY : integer ; GM, GD, JM, JD : byte ; Glast, Jlast : array [-1..+1] of word ; J : shortint ; begin Writeln(' Compare Greg And Juln Easter With Pesach') ; CompareHeader ; for GY := GYS to GYE do begin Write(GY:6) ; MJD := YMD_to_MJD(GrgCal, GY, 1, 1) ; Write(MJD:9) ; GregorianEaster(GY, GM, GD) ; GEMJD := YMD_to_MJD(GrgCal, GY, GM, GD) ; Write(GEMJD:9) ; JulianEaster(GY, JM, JD) ; JEMJD := YMD_to_MJD(JulCal, GY, JM, JD) ; Write(JEMJD:9) ; HY := GY + Three761 - 1 ; Write(HY:8) ; MJD := HYtoMJD(HY+1) ; Write(MJD:9) ; MJD := MJD-163 ; Write(MJD:9, WkDStr[DayOfWeek(MJD)]:4) ; Glast[CompareDiff(GEMJD, MJD)] := GY ; Jlast[CompareDiff(JEMJD, MJD)] := GY ; if GY=1981 then Write(' <-') ; Writeln ; { if GY=2005 then BREAK ; } end {GY} ; CompareHeader ; Writeln( 'Passover = Pesach = 15 Nisan = 163 days before first of next year'^M^J) ; Writeln(' Gregorian Julian') ; for J := -1 to 1 do Writeln(Glast[J]:10, Jlast[J]:10) ; end {CompareGregAndJulnEasterWithPesach} ; procedure DoSpans(const HYS, HYE, MaxSpan : integer) ; var HY, J, Span : integer ; Darr : array [0..6] of integer ; DSet : set of 0..6 ; begin Writeln(' Seek all-DoW spans within initial Hebrew Years ', HYS, -HYE) ; Writeln(' Span Last 7N+: 0 1 2 3 4 5 6', ' Days') ; for Span := 1 to MaxSpan do begin Write(Span:8) ; DSet := [] ; FillChar(DArr, SizeOf(DArr), 0) ; for HY := HYS to HYE do begin J := (HYtoMJD(HY+Span)-HYtoMJD(HY)) mod 7 ; if DArr[J]=0 then DArr[J] := HY ; Include(DSet, J) ; if DSet=[0..6] then begin Write(HY:8, '':6) ; for J := 0 to 6 do Write(DArr[J]:6) ; Writeln ; BREAK ; end ; end {HY} ; Write(^M) end {Span} ; end {DoSpans} ; procedure CheckPesachAgainstAList ; var F : text ; MJD, HP : MJDate ; HY : HebrYr ; GY : integer ; GM, GD : byte ; begin Writeln('Check Pesach Against A List') ; Write('Open file hebpesak.dat - ') ; Assign(F, 'hebpesak.dat') ; Reset(F) ; Writeln('OK') ; Writeln(' A.D. MJD DoW A.M. Calc.MJD DoW Diff') ; while not EoF(F) do begin Readln(F, GY, GM, GD) ; MJD := YMDtoMJD(GY, GM, GD) ; HY := GY + Three761 ; HP := HYtoMJD(HY) - 163 ; Write(GY:5, GM:3, GD:3, MJD:9, WkDstr[DayOfWeek(MJD)]:5, HY:9, HP:11, WkDstr[DayOfWeek(HP)]:5, (MJD-HP):6, ^M) ; if MJD<>HP then Writeln ; end ; Writeln('':77) ; Close(F) ; end {CheckPesachAgainstAList} ; function HebrLeap(const HY : HebrYr) : boolean ; begin HebrLeap := byte(HY mod 19) in [0, 3, 6, 8, 11, 14, 17] end {HebrLeap} ; procedure CheckYearLengthsPlausible ; var Y : HebrYr ; This, Next : MJDate ; Diff : longint ; Leap : boolean ; begin Writeln(' Check Year Lengths Plausible : to ', High(HebrYr)) ; Writeln(' Impossible results are followed by a line feed :') ; Writeln(' Heb Year First MJD Next RH Length Leap') ; This := HYtoMJD(Low(HebrYr)) ; for Y := Low(HebrYr) to Pred(High(HebrYr)) do begin Write(Y:9, This:11, #32) ; Next := HYtoMJD(Y+1); Write(Next:11, #32) ; Diff := Next-This ; Write(Diff:8) ; Leap := Diff>365 ; Write(Leap:8) ; if ((Diff-300) in [53, 54, 55, 83, 84, 85]) and Leap = HebrLeap(Y) then Write(^M) else Writeln ; This := Next end ; Writeln(^M^J'Done') ; end {CheckYearLengthsPlausible} ; function YearLength(const HY : HebrYr) : integer ; begin YearLength := HYtoMJD(HY+1) - HYtoMJD(HY) end {YearLength} ; type Six = 1..6 ; function CutLen(const HY : HebrYr) : Six ; var YL : integer ; begin YL := YearLength(HY) ; if YL<365 then CutLen := YL-352 else CutLen := YL-382+3 end {Cutlen} ; const UnCut : array [Six] of word = (353, 354, 355, 383, 384, 385) ; const Rept = 689472 ; procedure CheckYearFrequencies ; var Y : HebrYr ; L, XL : Six ; J : byte ; Total : longint ; YA : array [Six] of longint ; YYA : array [Six, Six] of longint ; YS : array [1..7] of longint ; const First = 1000 ; begin Writeln(' Check Year Length & Start Frequencies over ', Rept, ' years from ', First) ; FillChar(YA, SizeOf(YA), 0) ; FillChar(YYA, SizeOf(YYA), 0) ; FillChar(YS, SizeOf(YS), 0) ; XL := Cutlen(First-1) ; for Y := First to First+Rept-1 do begin Write(^M, Y:9, #32) ; Inc(YS[ISODoW1(HYtoMJD(Y))]) ; L := CutLen(Y) ; Inc(YA[L]) ; Inc(YYA[L, XL]) ; XL := L end ; Writeln(^M, '':11, ^M^J'Year start frequencies:') ; for J := 1 to 7 do Write(WkDstr[WkDys(J)]:9) ; Writeln ; for J := 1 to 7 do Write(YS[J]:9) ; Writeln(^M^J^M^J'Year length frequencies:'^M^J, ' Count & fraction :') ; Total := 0 ; for L := Low(Six) to High(Six) do begin Write(UnCut[L]:6, YA[L]:7) ; Inc(Total, YA[L]) end ; Writeln ; for L := Low(Six) to High(Six) do Write('':2, (YA[L]*(100000 div 16) div (Rept div 16)):7, 'e-5 ') ; Writeln(^M^J' in total ', Total) ; Total := 0 ; Writeln ; Write('Length') ; for XL := Low(Six) to High(Six) do Write(UnCut[XL]:7) ; Write(' followed by') ; for L := Low(Six) to High(Six) do begin Writeln ; Write(UnCut[L]:6) ; for XL := Low(Six) to High(Six) do begin Write(YYA[L, XL]:7) ; Inc(Total, YYA[L, XL]) end ; end ; Writeln(' in total ', Total) ; end {CheckYearFrequencies} ; procedure SeekRepeatSequence ; var Start : HebrYr ; After, SMax, Same : longint ; OK : boolean ; const K = 5730 {HebrYr} ; begin Writeln(' Seek Repeat Sequence (should be ', Rept, ')') ; Writeln(' After Length', ' ---------------- Hebrew Years ----------------') ; SMax := 0 ; for After := 1 to 1000000 do begin Write(After:8, #32) ; OK := true ; Same := 0 ; for Start := K to K+After-1 do begin if YearLength(Start) <> YearLength(Start+After) then begin OK := false ; BREAK end ; Inc(Same) ; end ; if Same>SMax then begin SMax := Same ; Writeln(Same:8, K:8, ' to', K+Same-1:8, ' matched by', K+After:8, ' to', K+After+Same-1:8) ; end ; if OK then Writeln(' OK') else Write(^M) ; end {After} ; Writeln('':77, ^M) ; end {SeekRepeatSequences} ; procedure SeekAllRepeatSequences ; var Start, From : HebrYr ; Sepn, S, SMax, SMaxMax : longint ; ThisEq : boolean ; const Kmax = 690000 ; begin Writeln(' Seek All Repeat Sequences') ; SMaxMax := 0 ; Writeln(' Separation Max Span From To = From To') ; for Sepn := 1 to Kmax do begin Write(^M, '':70, ^M, Sepn:8, #32) ; SMax := 0 ; S := 0 ; From := 1 ; for Start := 5700 to 5700+KMax+SMax do begin ThisEq := YearLength(Start) = YearLength(Start+Sepn) ; if ThisEq then Inc(S) else begin if S>SMax then begin SMax := S ; From := Start end ; S := 0 end ; end ; Write(SMax:8, From:12, From+Smax-1:8, From+Sepn:12, From+Sepn+Smax-1:8) ; if SMax>SMaxMax then begin SMaxMax := SMax ; Writeln end ; end {Sepn} ; Writeln('':77, ^M) ; end {SeekAllRepeatSequences} ; procedure Sextuplets ; const Six5 = 6*6*6*6*6 { 7776 } ; var From : HebrYr ; Count, J, Goes : longint ; Len : Six ; X, Y : word ; S6 : set of Six ; Arr : array [0..5] of Six ; BigArr : array [0..500{Six5}] of record A : array [boolean] of word ; W : word ; S : set of 0..18 ; D : set of WkDys end ; Start : array [0..18] of word ; begin Writeln(' Sextuplets covering all lengths - X is a sequence "label",', ' first observed:') ; Count := 0 ; Goes := 0 ; FillChar(BigArr, SizeOf(BigArr), 0) ; FillChar(Start, SizeOf(Start), 0) ; for From := 5700 to 5700+Rept-1 do begin Inc(Goes) ; S6 := [] ; if From mod 1000 = 0 then Write(^M, From:6, Count:6) ; for J := 0 to 5 do begin Len := CutLen(From+J) ; Include(S6, Len) ; Arr[J] := Len end ; if S6 <> [1..6] then CONTINUE ; { <----- } Inc(Count) ; Inc(Start[From mod 19]) ; X := 0 ; for J := 0 to 4 do X := 6*X + Arr[J] ; X := X-5500 { Range known small } ; with BigArr[X] do begin Y := From mod 19 ; Inc(W) ; Inc(A[Y > 9]) ; Include(S, Y) ; Include(D, DayOfWeek(HYtoMJD(From))) ; if W=1 then begin Write(^M, ' X=', X) ; for J := 0 to 5 do Write(From+J:6, YearLength(From+J):4) ; Writeln end ; end ; end ; Writeln(^M, '':18, 'Starting year can be year of cycle') ; Write('':6) ; for Y := 0 to 18 do Write(Y:3) ; Writeln('times':9) ; for X := Low(BigArr) to High(BigArr) do with BigArr[X] do if W>0 then begin Write(' X=', X) ; for Y := 0 to 18 do if Y in S then write(' +') else write(' ') ; for Y := 0 to 1 do Write(A[Y>0]:6) ; Writeln end ; Write('Starting day can be':21) ; for Y := 0 to 6 do Write(WkDstr[WkDys(Y)]:5) ; Writeln ; for X := Low(BigArr) to High(BigArr) do with BigArr[X] do if W>0 then begin Write(' X=', X, W:7, ' times ') ; for Y := 0 to 6 do if WkDys(Y) in D then write('+':5) else write('':5) ; Writeln end ; Writeln(' Total ', Count, ' times in ', Goes, ' years, of which a full sextuplet starts in') ; for X := 0 to 18 do if Start[X]>0 then Writeln(' year', X:3, ' of a cycle', Start[X]:5, ' times') ; end {Sextuplets} ; procedure GregDatesForAllHY ; var HY : HebrYr ; MJD : MJDate ; LY : longint ; GY : integer ; GM, GD : byte ; const D400 = 146097 ; Cap = ' HebYr 1st MJD Gregorian Diff' ; begin Writeln('Gregorian Dates for full repeat of Hebrew calendar:'^M^J, Cap) ; for HY := 1 to 690000 do begin MJD := HYtoMJD(HY) ; Write(HY:6, MJD:10) ; if MJD<0 then LY := 0 else begin LY := 400*(MJD div D400) ; MJD := MJD mod D400 end ; MJDtoYMD(MJD, GY, GM, GD) ; LY := GY+LY ; Write(LY:7, LZ(GM):3, LZ(GD):3, HY-LY:6) ; if HY=Rept then Write(' __') ; Writeln end ; Writeln(Cap) ; HALT end {GregDatesForAllHY} ; procedure SimpleLeap ; const NY : array [boolean] of char = ' *' ; var HY : HebrYr ; begin Writeln(' Simple Leap Year Stuff'^M^J) ; for HY := 1 to 19 do Write(HY:3) ; Writeln ; for HY := 1 to 19 do Write(NY[HebrLeap(HY)]:3) ; Writeln(^M^J) ; for HY := 5740 to 5799 do begin if HebrLeap(HY) then Write(HY:5) else Write('':5) ; if (HY mod 10) = 9 then Writeln ; end ; Writeln(' Consistency:') ; for HY := 700000 downto 1 do begin Write(^M, HY:7) ; if HebrLeap(HY) <> (YearLength(HY)>365) then Writeln ; end ; Write(^M) end {SimpleLeap} ; procedure IntervalSpanningYearLengths ; type Str50 = string [50] ; PLisT = ^LisT ; LisT = record Next : PList ; HY : HebrYr ; Ct : word ; St : Str50 end ; var HY1, HY2, MinY, MaxY : HebrYr ; MJD : MJDate ; P : PLisT ; M, Max, Min, MaxC, MinC : word ; Len : Six ; S6 : set of Six ; S7 : set of WkDys ; DW : WkDys ; B : byte ; S19 : set of 0..18 ; S : Str50 ; const Start = {5760} 1 ; PL : PList = NIL ; begin Max := 0 ; Min := 65535 ; MaxC := 0 ; MinC := 0 ; S7 := [] ; {$IFDEF DELPHI} MaxY := 1 ; MinY := 1 ; {$ENDIF to keep it happy} Writeln(' Check from ', Start, ' for ', Rept, ' years as start of run.'^M^J, ' Doing Run Min First Count Max First Count SMTWTFS Span') ; for HY1 := Start to Start+Rept-1 do begin Write(^M, HY1:6) ; S6 := [] ; for HY2 := HY1 to HY1+700000 {!} do begin Len := CutLen(HY2) ; Include(S6, Len) ; if S6=[1..6] then begin M := HY2-HY1+1 ; Write(M:5) ; if MMax then begin Max := M ; MaxY := HY1 ; MaxC := 0 ; S7 := [] ; S19 := [] end ; if M=Max then Inc(MaxC) ; Write(Min:6, MinY:6, MinC:6, {} Max:6, MaxY:6, MaxC:6, '':3) ; if M=Max then begin MJD := HYtoMJD(HY1) ; DW := DayOfWeek(MJD) ; Include(S7, DW) ; Include(S19, HY1 mod 19) ; for DW := Sun0 to Sat do if DW in S7 then Write('^') else write('.') ; MJD := HYtoMJD(HY2)-MJD ; Write(MJD:7, #32) ; if M=43 then begin for B := 0 to 18 do if B in S19 then Write(B:3) ; if (MJD<>15681) then begin Write(' 44 not 15681!') ; Readln end ; end ; S := '' ; for HY2 := HY1 to HY2-1 do S := S + char(48+CutLen(HY2)) ; P := PL ; while P<>NIL do begin if S=P^.St then begin Inc(P^.Ct) ; BREAK end ; P := P^.Next end ; if P=NIL then begin P := New(PList) ; P^.Next := PL ; P^.HY := HY1 ; P^.Ct := 1 ; P^.St := S ; PL := P end ; end ; BREAK end ; end ; end ; Writeln(^M, '':12, ^M^J' Prev First Pattern ... Last Next') ; Write('Min', Min:3, CutLen(Pred(MinY)):6, MinY:7, '':3) ; for HY1 := MinY to Pred(MinY+Min) do Write(CutLen(HY1)) ; Writeln(Pred(MinY+Min):7, CutLen(MinY+Min):4) ; Write('Max', Max:3, CutLen(Pred(MaxY)):6, MaxY:7, '':3) ; for HY1 := MaxY to (MaxY+Max-1) do Write(CutLen(HY1)) ; Writeln((MaxY+Max-1):7, CutLen(MaxY+Max{-1}):4) ; P := PL ; while P<>NIL do with P^ do begin if Length(St)=Max then Writeln(Ct:9, '*', HY:9, St:46) ; P := Next end ; end {IntervalSpanningYearLengths} ; procedure YearLengthsInCycles ; var HY1, HY2 : HebrYr ; Q : longint ; CC : word ; N, M : byte ; Miss : array [Six] of word ; J, K, Len : Six ; S6, SX6 : set of Six ; const Start = 303*19 ; begin Writeln(' Check from ', Start, ' for ', Rept, ' years as start of cycle,', ^M^J' counting year-lengths in 19 year cycles:'^M^J, ' Start year Included Excluded; Were Excluded') ; for Q := 1 to 19 do begin HY1 := Start ; SX6 := [] ; FillChar(Miss, SizeOf(Miss), 0) ; CC := 0 ; M := 0 ; repeat Write(^M, HY1:11) ; S6 := [] ; Inc(CC) ; for HY2 := Q+HY1 to Q+HY1+18 do begin Len := CutLen(HY2) ; Include(S6, Len) ; end ; Write('':4) ; for J := 1 to 6 do if J in S6 then Write(J) else Write('.') ; Write('':4) ; N := 0 ; for J := 1 to 6 do if J in S6 then Write('.') else begin Write(J) ; Inc(N) ; (* if N=2 then begin Writeln ; for HY2 := Q+HY1 to Q+HY1+18 do Write(YearLength(HY2):4) ; readln end ; *) end ; Write(N:2) ; if M= Start+Rept-1 ; if CC <> Rept div 19 then begin Write(' *(', CC, ')* ') ; Readln end ; Writeln(^M' First ', (Q+Start), -(Q+18+Start), ' Sometimes missing:':23) ; Write(' => for start year 19*N+', LZ(Q), ' Freqs:') ; for J := 1 to 6 do begin Write(Miss[J]:6) ; if J=3 then Write('':3) end ; Writeln(' M=', M) end {Q} ; Write('':35) ; for J := 1 to 6 do begin Write(UnCut[J]:6) ; if J=3 then Write('':3) end ; Writeln end {YearLengthsInCycles} ; procedure WriteYMD(const GY : integer ; const GM, GD : byte) ; begin Write(GY:7, '-', LZ(GM), '-', LZ(GD)) end {WriteYMD} ; procedure WriteHP(const p : longint) ; begin Write(p div 1080:3, 'h', p mod 1080:5, 'p') end {WriteHP} ; procedure WriteHYMolod1(const HY : HebrYr) ; var GY : integer ; GM, GD : byte ; d, p : longint ; begin HebMonthtoMolodDP(HYtoHebrewMonth(HY), d, p) ; HebDPtoGregYMDP(d, p, GY, GM, GD) ; WriteYMD(GY, GM, GD) ; WriteHP(p) ; end {WriteHYMolod1} ; procedure WriteGreg(const MJD : MJDate) ; var GY : integer ; GM, GD : byte ; begin MJDtoYMD(MJD, GY, GM, GD) ; WriteYMD(GY, GM, GD) ; Write(WkDStr[DayOfWeek(MJD)]:4) ; end {WriteGreg} ; procedure Cap ; begin Writeln('Hebrew L Dys MJD Gregorian 1st Pesach', ' ? Molod of Tishri ?') ; Writeln(' Year Y 1 Tishri (Passover)', ' ?GMT? ') ; end {Cap} ; procedure Calendar ; const LR : array [boolean] of char = ' *' ; var HY : HebrYr ; MJD : MJDate ; begin Cap ; for HY := 5700 to 6000 do begin MJD := HYtoMJD(HY) ; Write(HY:6, LR[HebrLeap(HY)]:2, YearLength(HY):4, MJD:8) ; WriteGreg(MJD) ; WriteGreg(HYtoMJD(HY+1)-163) ; WriteHYMolod1(HY) ; Writeln end ; Cap end {Calendar} ; procedure WritePartsAsHMS(p : word) ; var h, m, s, f : word ; begin h := p div 1080 ; p := p mod 1080 ; m := p div 18 ; p := p mod 18 ; s := (p*10) div 3 ; f := ((p*10) mod 3)*33 ; if f=66 then f := 67 ; Write(LZ(h):4, ':', LZ(m), ':', LZ(s), '.', LZ(f)) ; end {WritePartsAsHMS} ; procedure StatsForHY(HY : HebrYr) ; var MJD : MJDate ; GY : integer ; GM, GD : byte ; begin Writeln('AM':8, '1st MJD':9, 'Gregorian':17, 'Molod ?GMT?':21, 'Pesach':17) ; if HY<4000 then Inc(HY, Three761) ; MJD := HYtoMJD(HY) ; MJDtoYMD(MJD, GY, GM, GD) ; Write('**', HY:6, MJD:9, GY:6, LZ(GM):3, LZ(GD):3, ISODow1(MJD):3, WkDstr[DayOfWeek(MJD)]:4) ; WriteHYMolod1(HY) ; MJD := HYtoMJD(HY) - 163 ; MJDtoYMD(MJD, GY, GM, GD) ; Write(GY:7, LZ(GM):3, LZ(GD):3, {ISODow1(MJD):3,} WkDstr[DayOfWeek(MJD)]:4) ; Writeln ; HALT end {StatsForHY} ; procedure CurrentMolods ; var DM, HM, d, p : longint ; GY : integer ; GM, GD : byte ; {$IFNDEF DELPHI} X, {$ENDIF} Y, M : word ; begin Writeln(' ?GMT? of some Current Molods':30) ; {$IFDEF DELPHI} Y := 1900 + Trunc((Date+181)*4) div 1461 ; M := 0 ; {$ELSE} GetDate(Y, M, X, X) ; {$ENDIF} HM := HYtoHebrewMonth(Three761+Y-Ord(M<7)) ; Writeln(' Month Gregorian') ; for DM := 0 to 20 do begin Write(HM:7) ; HebMonthtoMolodDP(HM, d, p) ; HebDPtoGregYMDP(d, p, GY, GM, GD) ; WriteYMD(GY, GM, GD) ; WritePartsAsHMS(p) ; Inc(HM) ; Writeln end ; end {CurrentMolods} ; procedure Help ; begin Writeln( ' 0 params or just /? : this;'^M^J, ' 1 param :'^M^J, ' 0 : Greg Dates for all Hebrew Years of a Cycle {25 MB}'^M^J, ' 1 : Check Pesach Against A List - needs file hebpesak.dat'^M^J, ' 2 : Check Year Lengths Plausible'^M^J, ' 3 : Seek Repeat Sequence'^M^J, ' 4 : Seek All Repeat Sequences { takes ages }'^M^J, ' 5 : check MJDtoHY'^M^J, ' 6 : Check Year Frequencies'^M^J, ' 7 : Simple Leap Years'^M^J, ' 8 : Interval spanning year types'^M^J, ' 9 : Year types in 19-year cycles'^M^J, ' 10 : Calendar, AM 5700-6000 (inc Greg start, Pesach, Tishri)'^M^J, ' 11 : Seek Sextuplets of all year-lengths'^M^J, ' 12 : Current Molods'^M^J, ' > : Report on that Year : <4000 = AD, else AM'^M^J, ' Start, End : Greg Yrs for Passover/Easter comparison,'^M^J, ' Start, End, MaxSpan : Hebrew Year for all span-lengths mod 7 days.'^M^J, ' Further guidance may be found in comment in the source.'^M^J, ' Use Break or ^C to stop.') ; HALT end {Help} ; function GetParam(const N : word) : integer ; var J, P : integer ; begin Val(ParamStr(N), P, J) ; if J<>0 then begin Writeln('Param Error!') ; HALT(1) end ; GetParam := P end {GetParam} ; procedure FixedText ; var Q : longint ; begin Q := HYtoMJD(Rept+9)-HYtoMJD(9) ; Writeln(#32, Rept, ' Hebrew years is always ', Q, ' days; ', Q div 7, ' weeks plus ', Q mod 7, ' days;') ; Writeln(#32, Rept div 19, ' 19-year leap-cycles.', ' Year lengths 353..385 map to 1..6 as needed.') end {FixedText} ; BEGIN ; Writeln(^M'HEBCLNDR ', ParamStr(1), #32, ParamStr(2), #32, ParamStr(3), ' : www.merlyn.demon.co.uk >= 2005-02-11') ; if (ParamCount=0) or (ParamStr(1)='/?') then Help ; if (ParamCount=1) and (GetParam(1)>12) then StatsForHY(GetParam(1)) ; FixedText ; case ParamCount of 1 : case GetParam(1) of 0 : GregDatesForAllHY ; 1 : CheckPesachAgainstAList ; 2 : CheckYearLengthsPlausible ; 3 : SeekRepeatSequence ; 4 : SeekAllRepeatSequences ; 5 : InverseCheck ; 6 : CheckYearFrequencies ; 7 : SimpleLeap ; 8 : IntervalSpanningYearLengths ; 9 : YearLengthsInCycles ; 10 : Calendar ; 11 : Sextuplets ; 12 : CurrentMolods ; else Help ; end ; 2 : CompareGregAndJulnEasterWithPesach(GetParam(1), GetParam(2)) ; 3 : DoSpans(GetParam(1), GetParam(2), GetParam(3)) ; else Writeln('Wrong number of parameters.') end ; Write(' ? ') ; Readln ; END.