Thanksgiving and Chanukah

Eli Lansey

This code calculates when Thanksgiving and Chanukah will coincide.  See blog post here: http://lanseybrothers.blogspot.com/2010/12/chanuka-on-thanksgiving.html
I can be reached by email: ELansey@gmail.com
My webpage: http://eli.lansey.net

Serial Evaluation: Years 1863-3000

Needs["Calendar`"]

novdaysofweek[year_]:=Map[DayOfWeek[{year,11,#}]&,Range[1,30]]
novthursdays={#,Position[novdaysofweek[#],Thursday]}&/@Range[1863,3000]; (* From 1863 through the year 3000 *)
lastthursdays=Join[{#[[1]],11},Last@#[[2]]]&/@novthursdays;
fourththursdays=Join[{#[[1]],11},#[[2,4]]]&/@novthursdays;
thirdthursdays=Join[{#[[1]],11},#[[2,3]]]&/@Select[novthursdays,1938<#[[1]]<1942&];

(* This calculates the date of Thanksgiving *)
thanksgivings=Join[
Select[lastthursdays,#[[1]]<1942&] (* Before Roosevelt *),
thirdthursdays (* 1940-41 *),
Select[fourththursdays,1941<#[[1]]&] (* 1942- *),
Complement[
Select[lastthursdays,1941<#[[1]]<1957&],
Select[fourththursdays,1941<#[[1]]<1957&]
] (* Texas and others through 1956 *)
];
Rthanksgivings=Complement[
Select[lastthursdays,1940<#[[1]]<1957&],
Select[fourththursdays,1940<#[[1]]<1957&]
]; (* These are "Republican Thanksgivings" *)

(* This finds when Thanksgiving falls on the first day of Chanukah *)
jewishdate=CalendarChange[#,Gregorian,Jewish]&/@thanksgivings;
daysbetween=DaysBetween[{#[[1]],9,25},#,Calendar->Jewish]&/@jewishdate;
coincideJewishDateA=Extract[jewishdate,Position[daysbetween,_?NonNegative]]
coincideSecularDateA=SortBy[CalendarChange[#,Jewish,Gregorian]&/@coincideJewishDateA,First]

(* This finds when Thanksgiving falls on the first night of Chanukah *)
jewishdate=CalendarChange[#,Gregorian,Jewish]&/@thanksgivings;
daysbetween=DaysBetween[{#[[1]],9,24},#,Calendar->Jewish]&/@jewishdate;
coincideJewishDateB=Extract[jewishdate,Position[daysbetween,_?NonNegative]];
coincideSecularDateB=SortBy[CalendarChange[#,Jewish,Gregorian]&/@coincideJewishDateB,First];
coincideJewishDateC=Complement[coincideJewishDateB,coincideJewishDateA]
coincideSecularDateC=Complement[coincideSecularDateB,coincideSecularDateA]

Grid[SortBy[Join[Join[Partition[coincideSecularDateA[[All,1]],1]/.{p_}:>If[MemberQ[Intersection[coincideSecularDateA[[All,1]],Rthanksgivings[[All,1]]],p],{ToString[p]<>"*"},{ToString[p]}],(coincideJewishDateA/.{{_,_,25}:>{"First Day"},{_,_,28}:>{"Fourth Day"}}),2],Join[Partition[coincideSecularDateC[[All,1]],1]/.{p_}:>If[MemberQ[Intersection[coincideSecularDateC[[All,1]],Rthanksgivings[[All,1]]],p],{ToString[p]<>"*"},{ToString[p]}],(coincideJewishDateC/.{{_,_,24}:>{"First Night"}}),2]],First],Frame->All]

Parallel Long-Term Evaluations Years 3001-75000

LaunchKernels[]
ParallelNeeds["Calendar`"]

novdaysofweek[year_]:=Map[DayOfWeek[{year,11,#}]&,Range[1,30]]
DistributeDefinitions[novdaysofweek]

fourththursdays=ParallelMap[Join[{#,11},Position[novdaysofweek[#],Thursday][[4]]]&,Range[3001,75000]];(* From 3001 through the year 75000 *)
DistributeDefinitions[fourththursdays];

jewishdate=ParallelMap[CalendarChange[#,Gregorian,Jewish]&,fourththursdays];
DistributeDefinitions[jewishdate];

daysbetween=ParallelMap[DaysBetween[{#[[1]],9,25},#,Calendar->Jewish]&,jewishdate];
coincideJewishDate=Select[Extract[jewishdate,Position[daysbetween,_?NonNegative]],((#[[2]]==9&&#[[3]]≥25)||(#[[2]]==10&&#[[3]]≤3))&]  (* Wonky DaysBetween for Jewish year things, see Mathematica documentation. The Select picks out only those dates that could be Chanuka *)
coincideSecularDate=SortBy[CalendarChange[#,Jewish,Gregorian]&/@coincideJewishDate,First]

daysbetween=ParallelMap[DaysBetween[{#[[1]],9,24},#,Calendar->Jewish]&,jewishdate];
coincideJewishDate=Select[Extract[jewishdate,Position[daysbetween,_?NonNegative]],((#[[2]]==9&&#[[3]]≥25)||(#[[2]]==10&&#[[3]]≤3))&]
coincideSecularDate=SortBy[CalendarChange[#,Jewish,Gregorian]&/@coincideJewishDate,First]

Drifting Calendar

This calculates the number of days between Rosh HaShanah and Sept. 1 for each year from 1000CE to 50,000CE

LaunchKernels[]
ParallelNeeds["Calendar`"]

daysbetweenforPlot=ParallelMap[
{#,DaysBetween[{#,9,1},JewishNewYear[#],Calendar->Gregorian]}&,
Range[1000,50000]
];

and fits it to a straight line:

fittedmodel=LinearModelFit[daysbetweenforPlot,{1,x},x];
fit=Normal[fittedmodel]

It's a pretty good fit:

fittedmodel["RSquared"]

Show[
ListPlot[daysbetweenforPlot],
Plot[fit,{x,daysbetweenforPlot[[1,1]],(Last@daysbetweenforPlot)[[1]]},PlotStyle->{Red,Dashed}]
]

Days drift per year:

Coefficient[fit,x, 1]

Time to complete one complete cycle:

(365/(Coefficient[fit,x, 1]))

Passover in the Summer

(* Calculates the Gregorian date of Passover each Jewish year from 4000 to 25,000 *)
pesachs=ParallelMap[
CalendarChange[{#,1,14},Jewish,Gregorian]&,
Range[4000,25000]
];
DistributeDefinitions[pesachs]

(* Finds the number of days between Passover and Approximate summer solstice (June 20) *)
daysbetween=ParallelMap[DaysBetween[{#[[1]],6,20},#,Calendar->Gregorian]&,pesachs];

(* First year Passover is in the summer *)
First@Extract[pesachs,Position[daysbetween,_?NonNegative]]