I had to implement this in Javascript and was successful. So here's the simple programming logic I used:
Create an array (or list) of Parshas. Obviously you want to either use transliteration or such.
Then used a complex set of if statements to offset based on type of year. To figure the type of year use something like this:
function ytype(year){
var a,b,c
//ihly returns boolean if it's a leap year.
a=ihly(year)?1:0;
//get the first day of the hebrew year (1st of Tishrei)
var beg=gfxo(ffh(year,7,1));
var b=beg.getDay()+1;
//now based on what day of the week it is, set b
if (b==2){b=0;}
if (b==3){b=1;}
if (b==5){b=2;}
if (b==7){b=3;}
//get the first day of the next hebrew year
var end=gfxo(ffh(year+1,7,1));
//totdats=total day count of this year
totdays=(end.getTime()-beg.getTime())/24/60/60/1000;
//set c based on total days
if (totdays==353||totdays==383){c=0;}
if (totdays==354||totdays==384){c=1;}
if (totdays==355||totdays==385){c=2;}
//Now return: a=is it a leap year;
//b=day of week that year starts;
//c=total days type
return [a,b,c];
}
Then set up all your if statements to cover all the possibilities. There are 14 possibilities total (because some variations never happen), and 2 of the possibilities have the same rule of others. That leaves 12 if statements to cover. Based on the if statements, rearrange the array.
I'm going to start by defining some basic functions for manipulating the array:
function Psh(lp,add){
lp.unshift(add);
}
function Padd(lp,pos,add){
lp.splice(pos,0,add);
}
function Pcom(lp,pos){
var d='/';
lp[pos]=lp[pos]+d+lp[pos+1];
lp[pos+1]='TD';
}
function Pfin(lp){
for(i=0;i<lp.length;i++){
if(lp[i]=='TD'){
lp.splice(i,1);
i--;
}
}
}
And now we have the huge set of if statements:
//toy is the type of year array we got above
function parshaParse(toy){
//PARSHAS is the original array of parshiyos (['Bereishis','Noach',....])
var lp=PARSHAS.slice(0);
var a=toy[0],b=toy[1],c=toy[2];
if (a==0&&b==0&&c==0){
Pcom(lp,21);
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,25-1,'');//CHP
Psh(lp,'');//CHS
Psh(lp,'');//Haa
Psh(lp,'');//Vay
}
if(a==0&&b==0&&c==2||a==0&&b==1&&c==1){
Pcom(lp,21);
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,38);
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,25-1,'');//CHP
Padd(lp,32-1,'');//Shav2
Psh(lp,'');//CHS
Psh(lp,'');//Haa
Psh(lp,'');//Vay
}
if(a==0&&b==2&&c==2){
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,41);
Pfin(lp);
Padd(lp,26-1,'');//P7
Psh(lp,'');//CHS
Psh(lp,'');//YK
Psh(lp,'');//Haa
}
if(a==0&&b==2&&c==1){
Pcom(lp,21);
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,41);
Pfin(lp);
Padd(lp,25-1,'');//p1
Padd(lp,26-1,'');//p8
Psh(lp,'');//CHS
Psh(lp,'');//YK
Psh(lp,'');//Haa
}
if(a==0&&b==3&&c==0){
Pcom(lp,21);
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,41);
Pfin(lp);
Padd(lp,25-1,'');//p7
Psh(lp,'');//SHMA
Psh(lp,'');//Suk1
Psh(lp,'');//Haa
Psh(lp,'');//RH1
}
if(a==0&&b==3&&c==2){
Pcom(lp,21);
Pcom(lp,26);
Pcom(lp,28);
Pcom(lp,31);
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,25-1,'');//CHP
Psh(lp,'');//SHMA
Psh(lp,'');//Suk1
Psh(lp,'');//Haa
Psh(lp,'');//RH1
}
if(a==1&&b==0&&c==0){
Pcom(lp,38);
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,29-1,'');//CHP
Padd(lp,36-1,'');//Shav2
Psh(lp,'');//CHS
Psh(lp,'');//Haa
Psh(lp,'');//Vay
}
if(a==1&&b==0&&c==2||a==1&&b==1&&c==1){
Pcom(lp,41);
Pfin(lp);
Padd(lp,29-1,'');//P1
Padd(lp,30-1,'');//P8
Psh(lp,'');//CHS
Psh(lp,'');//Haa
Psh(lp,'');//Vay
}
if(a==1&&b==2&&c==0){
Padd(lp,30-1,'');//CHP
Psh(lp,'');//CHS
Psh(lp,'');//YK
Psh(lp,'');//Haa
}
if(a==1&&b==2&&c==2){
Pcom(lp,50);
Pfin(lp);
Padd(lp,30-1,'');//CHP
Psh(lp,'');//CHS
Psh(lp,'');//YK
Psh(lp,'');//Haa
}
if(a==1&&b==3&&c==0){
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,29-1,'');//CHP
Psh(lp,'');//SHMA
Psh(lp,'');//S1
Psh(lp,'');//Haa
Psh(lp,'');//RH1
}
if(a==1&&b==3&&c==2){
Pcom(lp,38);
Pcom(lp,41);
Pcom(lp,50);
Pfin(lp);
Padd(lp,29-1,'');//CHP
Padd(lp,36-1,'');//Shav2
Psh(lp,'');//SHMA
Psh(lp,'');//S1
Psh(lp,'');//Haa
Psh(lp,'');//RH1
}
//return the new array of parshiyos that is good for out type of year
return lp;
}
I don't have the time to explain what many of the abbreviations I used stood for. But this complex function will define a Parsha array for a given year in order of weeks.
Finally, look for the next Shabbos of today's date, take the offset of the shabbos date from the first shabbos of the year (i.e. the first Shabbos after 1 Tishrei) and divide by 7, to get # of weeks integer. Take the element of the array that corresponds to that integer.
Viola: you got the Parsha.
P.S. If you want more code: just ask.!
And here is additional code that deals with Hebrew dates:
You can ask me about acronyms in the comments. Remember, I wrote this code a while ago...
//also important for the general code:
function int(o){return parseInt(o);}
function ranger(x,y){
var a=new Array();
for (i=x; i < y; ++i){a.push(i);}
return a;
}
function nmod(x,y){
return ((x%y)+y)%y;
}
function amod(x,y){
//todo: might need a fix or 2
return y+nmod(x,(-y));
}
//some constants:
GREGORIANEPOCH=1;
HEBREWEPOCH=-1373427;
NISAN=1;
IYYAR=NISAN + 1;
SIVAN = NISAN + 2;
TAMMUZ = NISAN + 3;
AV = NISAN + 4;
ELUL = NISAN + 5;
TISHRI = NISAN + 6;
MARHESHVAN = NISAN+ 7;
KISLEV = NISAN + 8;
TEVET = NISAN + 9;
SHEVAT = NISAN + 10;
ADAR = NISAN + 11;
ADARI = NISAN + 11;
ADARII = NISAN + 12;
function dihy(year){return hny(year + 1) - hny(year);}
function ihly(year){return ((7*year + 1) % 19) < 7;}
function ilm(year){return dihy(year) in {355:1,385:1};}
function isk(year){return dihy(year) in {353:1, 383:1};}
function gyfx(date){
approx = Math.floor((date - GREGORIANEPOCH + 2) * 400 / 146097);
start = GREGORIANEPOCH + 365 * approx + Math.floor(approx/4) - Math.floor(approx/100) + Math.floor(approx/400);
if (date < start){return int(approx);}
else{return int(approx + 1);}
}
function ffg(year,month,day){
m = amod((month - 2), 12);
y = year + Math.floor((month + 9)/12);
return int(GREGORIANEPOCH - 1 - 306 + 365 *(y - 1) + Math.floor((y - 1)/4) - Math.floor((y - 1)/100) + Math.floor((y - 1)/400) + Math.floor((3*m - 1)/5) + 30*(m - 1) + day);
}
function gfx(date){
y = gyfx(GREGORIANEPOCH - 1 + date + 306);
priorDays = date - ffg(y - 1, 3, 1);
month = int(amod(Math.floor((5*priorDays + 155)/153) + 2, 12));
year = int(y - Math.floor((month + 9)/12));
day = int(date - ffg(year, month, 1) + 1);
return [year, month, day];
}
function gfxo(date){
var a=gfx(date);
return new Date(a[0],a[1]-1,a[2]);
}
function lmohy(year){
if (ihly(year)){return 13;}
else{return 12;}
}
function ldohm(year,month){
if ((month in {2:1, 4:1, 6:1, 10:1, 13:1})||(month == 12 && !(ihly(year)))||(month == 8 && !(ilm(year)))||(month == 9 && isk(year))){return 29;}
else{return 30;}
}
function hced(year){
monthsElapsed = int(Math.floor((235*year - 234)/19.0));
partsElapsed = 12084 + 13753*monthsElapsed;
day = 29 * monthsElapsed + int(Math.floor(partsElapsed/25920.0));
if ((3*(day + 1) % 7) < 3){return day + 1;}
else{return day;}
}
function hnyd(year){
ny0 = hced(year - 1);
ny1 = hced(year);
ny2 = hced(year + 1);
if ((ny2 - ny1) == 356){return 2;}
else if ((ny1 - ny0) == 382){return 1;}
else{return 0;}
}
function hny(year){return HEBREWEPOCH + hced(year) + hnyd(year);}
function ffh(year, month, day){
if (month < TISHRI){ms = ranger(TISHRI, lmohy(year) + 1).concat(ranger(NISAN, month));}
else{ms = ranger(TISHRI, month);}
yearly=year;
return hny(year) + day - 1 + sum(ms.map(function lmb(x){return ldohm(yearly,x);}))
}
In Israel if 8th day Pesach is Shabbat in a 13-month year they are ahead of us until Matot-Masei which means they read Naso before Shavuot.
You don't really need the last rule. Nitzavim and Vayeilech are the only sedras in D'varim that can be combined. So that rule automatically applies.