Take the 2-minute tour ×
Mi Yodeya is a question and answer site for those who base their lives on Jewish law and tradition and anyone interested in learning more. It's 100% free, no registration required.

I'm writing a site where the user would be able to see the calendar with jewish-civil translation of dates, and also which parasas shavua falls on which Shabbos.

I'd like to know what is the formula of calculating which parashas shavua we read on Shabbos that is given by Jewish date. Obviously the calculation differs between Israel and Diaspora. Both variants are needed.

thanks.

share|improve this question

3 Answers 3

I'm sure that there are modules already written for this purpose (since, after all, there are lots of existing sites and applications that show the parshah of the week, and I doubt each of them reinvented the wheel). I don't know of any that are freely available, though.

One way of doing this would be to use lookup tables for each of the 14 possible year types. But if you want to figure out the weekly parshiyos from first principles, then the facts you need are as follows:

  • Start with the fact that Parshas Bereishis is read on the first Shabbos following the 22nd of Tishrei (Shemini Atzeres).

  • Every Shabbos of the year has to have a weekly parshah, unless it coincides with a major holiday (Pesach, Shavuos, Rosh Hashanah, Yom Kippur, Sukkos, or Shemini Atzeres).

  • There are seven (in Israel, six) pairs of parshiyos that can be doubled up: Vayakhel-Pekudei, Tazria-Metzora, Acharei-Kedoshim, Behar-Bechukosai, Chukas-Balak (only outside Israel), Matos-Mas'ei, and Nitzavim-Vayelech.

  • Vezos Haberachah will always be on Simchas Torah (or in Israel, Shemini Atzeres), whether it's on Shabbos or not.

Then apply the following rules, given in Shulchan Aruch, Orach Chaim 428:4:

  • In a regular year, the Shabbos before Pesach is always Parshas Tzav. In a leap year, it is Metzora (or, when Rosh Hashanah was on Thursday, Acharei Mos).

    To satisfy this rule, Vayakhel-Pekudei will be combined in most regular years (except for the case where Rosh Hashanah was on Thursday and the year is "complete," because then there's an extra Shabbos available between Simchas Torah and Pesach). They will be separated in all leap years.

  • The Shabbos before Shavuos is Parshas Bamidbar (except in leap years in which Rosh Hashanah was on Thursday, when it is Naso).

    To satisfy this rule, in a regular year there will have to be three sets of parshiyos in the Book of Vayikra that are combined: Tazria-Metzora, Acharei-Kedoshim, and Behar-Bechukosai. (The exception is in Israel, in years when Pesach begins on Shabbos, because then 22 Nissan has a weekly parshah there, as it's a regular Shabbos. In that case, in Israel, Behar and Bechukosai are separated.) All three of these pairs of parshiyos will be separated in leap years.

  • The Shabbos after Tish'a Be'Av is Parshas Va'eschanan.

    To satisfy this rule, in most years Matos-Mas'ei will have to be combined. The exceptions are leap years in which Rosh Hashanah was on Thursday, and in Israel, also leap years when Pesach began on Shabbos.

    Also, outside of Israel, in years when Shavuos is on Friday and Shabbos, Chukas-Balak will have to be combined.

    (Depending on how universal you want your site to be, you may need to also consider variant customs. I believe that some Yemenite communities reverse the rules of when Chukas-Balak vs. Matos-Mas'ei are combined.)

  • The Shabbos before Rosh Hashanah is Nitzavim.

    To satisfy this rule (and still have all of the parshiyos completed by Simchas Torah), in years when Rosh Hashanah is on Thursday or Shabbos, Nitzavim-Vayelech are combined and read on the Shabbos before Rosh Hashanah.

share|improve this answer

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);}))
}
share|improve this answer
1  
I need it in JS too, so if you have more code it would be very helpful. tnx. –  jutky Nov 21 '10 at 19:31
3  
First proper use of the Code Sample format on m.y! –  Isaac Moses Nov 21 '10 at 22:20
    
If you could also post the code of functions gfxo and ffh it would be great. thanks. –  jutky Nov 22 '10 at 6:27
    
Will get to that as soon as I'm by a computer. They're basically functions for Hebrew date calculation –  yydl Nov 22 '10 at 23:06
    
Thanks again. Still there missing definition of ihly, ilm and isk functions. Also a slight uncryption of the acronyms would be helpful –  jutky Nov 23 '10 at 12:46
up vote 3 down vote accepted

I've asked a friend of mine to do me a favor and to write a code for this.

Here is what he have done, and here is an example of (my) usage of his code.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.