// Javascript zur Konvertierung von Kalendersystemen
// (c) Arndt Brünner, 24.8.2002
//           Version: 25.8.2002

var D=new Date();
var d=new Date_(D.getYear(),D.getMonth()+1,D.getDate(),D.getHours(),D.getMinutes(),D.getSeconds(),2);
var hd=new Date_(D.getYear(),D.getMonth()+1,D.getDate(),D.getHours(),D.getMinutes(),D.getSeconds(),0);

if((d.j<1000)&&(d.j>=100))d.j+=1900; // Netscape gibt Jahr zweistellig ab 1900 aus.
if((d.j<1000)&&(d.j<100))d.j+=2000; 

var DeuM=new Array("Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
var HebrM=new Array("Tishri","Heshvan","Kislev","Tevet","Shevat","Adar","Veadar","Nisan","Iyar","Sivan","Tammuz","Av","Elul");
var HebrMalt=new Array("Tischri",0,"Tishri",0,"Heschvan",1,"Heshvan",1,"Tewet",3,"Schewat",4,"Schevat",4,"Adar sheni",6,"Adar-sheni",6,"We-Adar",6,"Iyar",8,"Iyyar",8,"Ijjar",8,"Siwan",9,"Tammus",10);
var IslM=new Array("Muharram","Safar","Rabi al-Awwal","Rabi al-Akhir" ,"Djumada l-Ula","Djumada l-Akhira", "Radjab","Shaban","Ramadan","Shawwal","Dhu l-Kada","Dhu l-Hidjdja");
var IslMalt=new Array("Muharram",0,"Safar",1,"Rabi'al-Awwal",2,"Rabi al-Awwal",2,"Rabi ul-Awwal",2,"Rabi'ath-Thani",3,"Rabi al-Akhir",3,"Rabi ul-Akhir",3,"Jumada l-Ula",4,"Djumada l-Ula",4,"Jumada t-Tania",5,"Djumada l-Akhira",5,"Rajab",6,"Radjab",6,
                      "Radschab",6,"Sha'ban",7,"Shaban",7,"Schaban",7,"Ramadan",8,"Shawwal",9,"Schawwal",9,"Dhu l-Qa'da",10,"Dhu l-Kada",10,"Dhu l-Hijja",11,"Dhu l-Hidjdja",11,"Dhu-l-Hidscha",11,"Dhu-l-Hiddscha",11);
var RomM=new Array("Ianuarii","Februarii","Martii","Aprilis","Maii","Iunii","Iulii","Augusti","Septembri","Octobri","Novembri","Decembri")
var RomWT=new Array("Solis","Lunae","Martis","Mercurii","Iovis","Veneris","Saturni");
//speichert den Tag des Passahfestes im Jahr j im Date_()-Objekt date im Julianischen Kalender
//und gibt den Tag als jd zurück
function getPassah(jahr,date)
{
	var C=INT(jahr/100),S=0/*INT((3*C-5)/4)*/,A=jahr+3760,a=(12*jahr+12)%19,b=jahr%4;
	var Q=-1.904412361576+1.554241796621*a+0.25*b-0.003177794022*jahr+S;
	var j=(INT(Q)+3*jahr+5*b+2-S)%7,r=Q-INT(Q),D=0;
	if((j==2)||(j==4)||(j==6))D=INT(Q)+23;
	else if((j==1)&&(a>6)&&(r>=0.632870370))D=INT(Q)+24;
	else if((j==0)&&(a>11)&&(r>=0.897723765))D=INT(Q)+23;
	else D=INT(Q)+22;	
	date.j=jahr;
	date.m=(D>31)?4:3;
	date.t=(D<32)?D:D-31;
	date.h=12;date.n=0;date.s=0;
	date.typ=1;
	return GetJulianDay(date);
}

//gibt die Länge des hebräischen Jahres x zurück
function getHebrJL(x)
{
	var j1=getPassah(x-3760,hd),j0=getPassah(x-3761,hd);
	return INT(j1-j0+.1);
}

function isHebrSchaltjahr(j)
{
	var r=j%19;
	return((r==0)||(r==3)||(r==6)||(r==8)||(r==11)|(r==14)||(r==17))
}

//speichert das hebr. Neujahr des greg. Jahres x in date (Julianisch) und gibt ihn als jd zurück
function getHebrNeujahr(x,date)
{
	var j=getPassah(x,date)+163;
	date.typ=1;
	GetDateFromJD(j,date);
	return j;
}

//gibt das hebr. Datum vom Julianischen Tag jd als String zurück
function getHebrFromJD(jd)
{
	hd.typ=1;
	GetDateFromJD(jd,hd);
	var nj=getHebrNeujahr(hd.j,hd); // nj= JulTag des hebr. Neujahrs
	if(nj>jd)nj=getHebrNeujahr(--hd.j,hd); 
	var t=INT(jd-nj+.5)+1; // Tag im hebr. Jahr
	var L=getHebrJL(hd.j+3761); // Jahreslänge: 353, 354, 355 ; 383, 384, 385 Tage
//alert(hd.j+3761+"\nL="+L+"\nt="+t);
	var m=0;
	do{
	if(t>30){m++;t-=30;}else break;  // Tishri
	if(L%10==5){if(t>30){m++;t-=30;}else break;}  //Heshvan
	if(L%10!=5){if(t>29){m++;t-=29;}else break;}
	if(L%10==3){if(t>29){m++;t-=29;}else break;}  //Kislev
	if(L%10!=3){if(t>30){m++;t-=30;}else break;}
	if(t>29){m++;t-=29;}else break; //Tevet
	if(t>30){m++;t-=30;}else break; //Shevat
	if(L>380){if(t>30){m++;t-=30;}else break;}  //Adar
	if(L<380){if(t>29){m++;t-=29;}else break;}
	m++;
	if(L>380){if(t>29){t-=29;}else break;} //Veadar
	if(t>30){m++;t-=30;}else break; //Nisan
	if(t>29){m++;t-=29;}else break; //Iyar
	if(t>30){m++;t-=30;}else break; //Sivan
	if(t>29){m++;t-=29;}else break; //Tammuz
	if(t>30){m++;t-=30;}else break; //Av
	}while(false);
	//if((m<0)||(m>12))alert(m);
	return t+". "+HebrM[m]+" "+(hd.j+3761);
}

function getJDFromHebr(h)
{
	h=h.replace(/\./g," ").replace(/ +/g," ").replace(/sch/g,"sh").replace(/w/g,"v");
	var x=h.split(" ");
	if(x.length!=3)return -999999999;
	var t=Number(x[0]),m=x[1],j=Number(x[2]),mi=-1;
	for(mi=0;mi<13;mi++)if(m.toLowerCase()==HebrM[mi].toLowerCase())break;
	if(mi==13)
	{
		for(i=0;i<HebrMalt.length;i+=2)
			if(m.toLowerCase()==HebrMalt[i].toLowerCase())
				{mi=Number(HebrMalt[i+1]);break;}
	}
	if(mi==13)return -999999999;
	var nj=getHebrNeujahr(j-3761,hd);
	var L=getHebrJL(j);
	if((mi==6)&&(L<380))return -999999999;
	if(mi>0)nj+=30;
	if((L%10==5)&&(mi>1))nj+=30;
	if((L%10!=5)&&(mi>1))nj+=29;
	if((L%10==3)&&(mi>2))nj+=29;
	if((L%10!=3)&&(mi>2))nj+=30;
	if(mi>3)nj+=29;
	if(mi>4)nj+=30;
	if((L>380)&&(mi>5))nj+=30;
	if((L<380)&&(mi>5))nj+=29;
	if((L>380)&&(mi>=6))nj+=29;
	if(mi>7)nj+=30;
	if(mi>8)nj+=29;
	if(mi>9)nj+=30;
	if(mi>10)nj+=29;
	if(mi>11)nj+=30;
	nj+=t-1;
	return nj;
}

function getIslFromJD(j)
{
	if(j<1948440)return "";
	hd.typ=1;
	GetDateFromJD(j,hd);
	var fj=(hd.j==622);
	if(fj)hd.j+=521;
	var X=hd.j,M=hd.m,D=hd.t,
	W=((X%4)==0)?1:2,
	N=INT(275*M/9)-W*INT((M+9)/12)+D-30,
	A=X-623,B=INT(A/4),C=A%4,C1=365.2501*C,C2=INT(C1);
	if(C1-C2>0.5)C2+=1;
	var DD=1461*B+170+C2,Q=INT(DD/10631),R=DD%10631,
	J=INT(R/354),K=R%354,O=INT((11*J+14)/30),
	H=30*Q+J+1,JJ=K-O+N-1;
	if(JJ>354)
	{
		var DL=(11*(H%30)+3)%30;
		if(DL<19){JJ-=354;H++;}
		if(DL>18){JJ-=355;H++;}
		if(JJ==0){JJ=355;H--;}
	}
	var S=INT((JJ-1)/29.5),m=1+S,d=INT(JJ-29.5*S);
	if(JJ==355){m=12;d=30;}
	if(fj){H=1;}
	return d+". "+IslM[m-1]+" "+H;
}

function getJDFromIsl(t,m,j)
{
	var H=j,M=m,D=t,
	N=D+INT(29.501*(M-1)+0.99),
	Q=INT(H/30),R=H%30,A=INT((11*R+3)/30),
	W=404*Q+354*R+208+A,Q1=INT(W/1461),Q2=W%1461,
	G=621+4*INT(7*Q+Q1),K=INT(Q2/365.2422),
	E=INT(365.2422*K),J=Q2-E+N-1,X=G+K;
	if((J>366)&&((X%4)==0)){J-=366;X++;}
	if((J>365)&&((X%4)>0)){J-=365;X++;}
	hd.typ=1;hd.j=X;hd.h=12;hd.n=0;hd.s=0;
	GetDateFromDayOfYear(J,hd);
	return GetJulianDay(hd);
}

function getJDFromIslStr(I)
{
	var x=I.split(" "); 
	if(x.length!=3)return;
	var t=Number(x[0]),m=x[1],j=Number(x[2]),mi=-1;
	for(mi=0;mi<13;mi++)if(m==IslM[mi])break;
	if(mi==13)return;
	return getJDFromIsl(t,mi+1,j);
}

function parseIslDate(t,d)
{
	var j=-1;
	while(t.charAt(0)==" ")t=t.substr(1,t.length);
	while(t.charAt(t.length-1)==" ")t=t.substr(0,t.length-1);
	for(i=0;i<12;i++)if((j=t.toLowerCase().indexOf(IslM[i].toLowerCase()))>-1){t=t.substr(0,j)+" "+(i+1)+" "+t.substring(j+IslM[i].length+1,t.length);break;}
	for(i=0;i<HebrMalt.length;i+=2)
		if((j=t.toLowerCase().indexOf(HebrMalt[i].toLowerCase()))>-1){t=t.substr(0,j)+" "+(Number(HebrMalt[i+1])+1)+" "+t.substring(j+HebrMalt[i].length+1,t.length);break;}
	t=t.replace(/\./g," ").replace(/ +/g," ");
	var x=t.split(" ");
	if(x.length!=3)return false;
	d.t=Number(x[0]);d.m=Number(x[1]);d.j=Number(x[2]);	
	return (d.j>0);
}
function parseHebrDate(t,d)
{
	var j=-1;
	t=t.replace(/sch/g,"sh").replace(/w/g,"v")
	while(t.charAt(0)==" ")t=t.substr(1,t.length);
	while(t.charAt(t.length-1)==" ")t=t.substr(0,t.length-1);
	for(i=0;i<13;i++)if((j=t.toLowerCase().indexOf(HebrM[i].toLowerCase()))>-1){t=t.substr(0,j)+" "+(i+1)+" "+t.substring(j+HebrM[i].length+1,t.length);break;}
	for(i=0;i<HebrMalt.length;i+=2)
		if((j=t.toLowerCase().indexOf(HebrMalt[i].toLowerCase()))>-1){t=t.substr(0,j)+" "+(Number(HebrMalt[i+1])+1)+" "+t.substring(j+HebrMalt[i].length+1,t.length);break;}
	t=t.replace(/\./g," ").replace(/ +/g," ");
	var x=t.split(" ");
	if(x.length!=3)return false;
	d.t=Number(x[0]);d.m=Number(x[1]);d.j=Number(x[2]);	
	return true;
}
function parseRomDate(t,D)
{
	var x,i,d=99,z,k=0,m=-1,j=-999999.25,n,sj,bisvi=1==0,jj;
	romD="";
	t=String(t);if((t=="")||(t==null))return false;
	t=t.toLowerCase().replace(/ +/g," ").replace(/j/g,"i").replace(/ante /,"").replace(/diem /,"");
	if(t.indexOf("bis vi")>-1){t=t.replace(/bis vi/,"");bisvi=1==1;d=-6.6}
	x=t.split(" ");//alert(x);
	for(i=0;i<x.length;i++)
	{
		if((x[i]=="")||(x[i]==null))continue;
		if(x[i]=="kalendis"){d=0;k=1;continue;}
		if(x[i]=="kalendae"){d=0;k=1;continue;}
		if(x[i]=="nonis"){d=0;k=2;continue;}
		if(x[i]=="nonae"){d=0;k=2;continue;}
		if(x[i]=="idibus"){d=0;k=3;continue;}
		if(x[i]=="pridie"){d=-1;continue;}
		if(x[i]=="kalendas"){k=1;continue;}
		if(x[i]=="nonas"){k=2;continue;}
		if(x[i]=="idus"){k=3;if(d==99)d=0;continue;}
		if(x[i].substr(0,3)=="kal"){k=1;if(d==99)d=0;continue;}
		if(x[i].substr(0,3)=="non"){k=2;if(d==99)d=0;continue;}
		if(x[i].substr(0,2)=="id"){k=3;if(d==99)d=0;continue;}
		z=roem_dez(x[i]);if(z>0){if((d==99)&&(z<20))d=-z+1;else{if(d<99)j=z;}continue;}
		for(jj=0;jj<12;jj++)
		{
			if(x[i]==RomM[jj].toLowerCase()){m=jj+1;break;}
			if(x[i].substr(0,3)==RomM[jj].toLowerCase().substr(0,3)){m=jj+1;break;}
		}if(jj<12)continue;
		return false;
	}
	if((k>0)&&(d==99))d=0;
	//alert(d+" "+k+" "+m+" "+j);
	if((d>90)||(m==-1)||(j==-999999.25))return false;
	sj=IsSchaltjahr(j,D.typ)==-1;
	if((!sj)&&(bisvi))return false;
	if((bisvi)&&((m!=3)||(k!=1)))return false;
	switch(k)
	{
	case 1:if(d==0){n=1;break;}
		var ml=Monatslaenge[(m+10)%12];if((m==3)&&(sj))ml++;
		if((m==3)&&(d<0)){if((sj)&&(d<-4))d--;if(d==-7.6)d=-5;}
		n=ml+d+1;m--;if(m==0){m=12;j--;}
		if(n<=Iden(m))return false;
		break;
	case 2:n=Nonen(m)+d;break;
	case 3:n=Iden(m)+d;if(d<=-8)return false;break;
	default:return false;
	}
	if(n<1)return false;
	D.m=m;D.t=n;D.j=j;getRomDate(D);
	return true;
}
function getRomDate(d)
{
	rerw=false;if((d.dateStr().indexOf("undef")>-1)||(d.dateStr().indexOf("NaN")>-1))return "";
	var sj=IsSchaltjahr(d.j,d.typ)==-1,ml=Monatslaenge[d.m-1],t="",j=d.j,D="";
	if((sj)&&(d.m==2))ml++; 
	if((d.t>ml)||(d.t<1))return "";
	if(d.j<8)return "";
	var N=Nonen(d.m),I=Iden(d.m);
	if(d.t==1){t="kalendis ";D="An den Kalenden";}
	if((d.t>1)&&(d.t<N-1)){t=dez_roem(N-d.t+1)+" nonas ";D=String(N-d.t)+" Tage vor den Nonen";}
	if(d.t==N-1){t="pridie nonas ";D="Am Vortag der Nonen";}
	if(d.t==N){t="nonis ";D="An den Nonen";}
	if((d.t>N)&&(d.t<I-1)){t=dez_roem(I-d.t+1)+" idus ";D=String(I-d.t)+" Tage vor den Iden";}
	if(d.t==I-1){t="pridie idus ";D="Am Vortag der Iden";}
	if(d.t==I){t="idibus ";D="An den Iden";}
	t+=RomM[d.m-1];D+=" des "+DeuM[d.m-1];
	if((d.t>I)&&(d.t<ml)){t=dez_roem(ml+1-d.t+1)+" kalendas "+RomM[d.m%12];if(d.m==12)j++;D=String(ml+1-d.t)+" Tage vor den Kalenden des "+DeuM[d.m%12];}
	if((sj)&&(d.m==2)&&(d.t==25)){t="bis VI kalendas Martii";D="5 Tage vor den Kalenden des März";}
	if((sj)&&(d.m==2)&&(d.t<25)&&(d.t>13)){t=dez_roem(ml+1-d.t)+" kalendas Martii";D=String(ml+1-d.t)+" Tage vor den Kalenden des März";}
	if(d.t==ml){t="pridie kalendas "+RomM[d.m%12];if(d.m==12)j++;D="Am Vortag der Kalenden des "+DeuM[d.m%12];}
	t+=" "+dez_roem(j);D+="s des Jahres "+j;
	if(t.indexOf("bis ")>-1)D+="\n(Schalttag)";
	romD=D.replace(/zs/,"z");
	return t;
}
function getRomFromJD(j)
{
	var dd=new Date_();dd.typ=1;
	GetDateFromJD(j,dd);
	return getRomDate(dd);
}
var Monatslaenge=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var romD="";
function Iden(m){if((m==3)||(m==5)||(m==7)||(m==10))return 15; else return 13;}
function Nonen(m){return Iden(m)-8;}

function getHebrFeiertage(j)
{
	var typ=(j<5343)?1:2;
	hd.typ=typ;
	var t="Hebräische Feste und Feiertage des hebräischen Jahres "+j+"\nim "+((typ==2)?"gregorianischen":"julianischen")+" Kalender\n";
	var jd=getJDFromHebr("1. Tishri "+j);
	t+="\nRosh ha-Shanah (Neujahr, 1. und 2. Tishri):\n             "+getDateStrFromJD(jd,typ)+" und "+getDateStrFromJD(jd+1,typ);
	t+="\nJom Kippur (10. Tishri): "+getDateStrFromJD(jd+9,typ);
	t+="\nSukkot (15. Tishri): "+getDateStrFromJD(jd+14,typ);
	t+="\nSukkot (22. Tishri, außerhalb Israels 23. Tishri):\n             "+getDateStrFromJD(jd+21,typ)+" bzw. "+getDateStrFromJD(jd+22,typ);
	jd=getJDFromHebr("15. Nisan "+j);
	t+="\nPassahfest (15. - 21. Nisan, außerhalb Israels bis 22. Nisan):\n             "+getDateStrFromJD(jd,typ)+" - "+getDateStrFromJD(jd+6,typ)+" bzw. "+getDateStrFromJD(jd+7,typ);
	jd=getJDFromHebr("5. Iyar "+j);
	t+="\nJom ha-Azma'ut (Unabhängigkeitstag, 5. Ijjar): "+ getDateStrFromJD(jd,typ);
	jd=getJDFromHebr("6. Sivan "+j);
	t+="\nShawuot (6. Sivan): "+ getDateStrFromJD(jd,typ);
	t+="\n\nHalbfeiertage:\n";
//     10. Tewet,
	jd=getJDFromHebr("10. Tevet "+j);
	t+="\n10. Tewet: "+getDateStrFromJD(jd,typ);
//     Tu bi-Schewat: 15. Schewat,
	jd=getJDFromHebr("15. Shevat "+j);
	t+="\nTu bi-Schewat (15. Schewat): "+getDateStrFromJD(jd,typ);
//     Ta'anith-Esther: 13. Adar (falls dieser auf einen Sonnabend fällt, wird dieser Halbfeiertag am
//     vorhergehenden Donnerstag begangen),
	jd=getJDFromHebr("13. Adar "+j);
	GetDateFromJD(jd,d);
	if(GetWeekday(d)==6)jd-=2;
	t+="\nTa'anith-Esther (13. Adar, falls dies ein Samstag ist, am 11. Adar):\n             "+getDateStrFromJD(jd,typ);
//     Jom ha-Schoah (Holocaust-Gedenktag): 27. Nisan,
	jd=getJDFromHebr("27. Nisan "+j);
	t+="\nJom ha-Schoah (Holocaust-Gedenktag, 27. Nisan): "+getDateStrFromJD(jd,typ);
//     Lag ba-Omer: 18. Ijjar,
	jd=getJDFromHebr("18. Ijjar "+j);
	t+="\nLag ba-Omer (18. Ijjar): "+getDateStrFromJD(jd,typ);
//     17. Tammus und 9. Aw (werden auf Sonntag verschoben, falls sie auf einen Sonnabend fallen) sowie
 //    der     15. Aw.
	jd=getJDFromHebr("17. Tammuz "+j);
	GetDateFromJD(jd,d);
	if(GetWeekday(d)==6)jd++;
	t+="\n17. Tammus und 9. Aw (falls dies Samstage sind, am Tag darauf):\n             "+getDateStrFromJD(jd,typ)+" und "+getDateStrFromJD(jd+21,typ);
//     Weitere Feste sind:
	t+="\n\nWeitere Feste:\n";
//     Chanukkah: 8 Tage, beginnend mit dem 25. Kislew und
	jd=getJDFromHebr("25. Kislev "+j);
	t+="\nChanukkah: (8 Tage ab dem 25. Kislev):\n             "+getDateStrFromJD(jd,typ)+" - "+getDateStrFromJD(jd+7,typ);
///     Purim: 14. Adar (in Schaltjahren Adar sheni).
	jd=getJDFromHebr("14. "+((isHebrSchaltjahr(j))?"Veadar ":"Adar ")+j);
	t+="\nPurim (14. Adar, in Schaltjahren Veadar):\n             "+getDateStrFromJD(jd,typ);
	return t;
}

function getIslFeiertage(j)
{
	var typ=(j<=990)?1:2;
	hd.typ=typ;
	var t="Islamische Feste und Feiertage des islamischen Jahres "+j+"\nim "+((typ==2)?"gregorianischen":"julianischen")+" Kalender\n";
	t+="\n   (vom Sonnenuntergang der angegebenen Tage \n   bis zum Sonnenuntergang am folgenden Tag.)\n";
	var jd=getJDFromIsl(1,1,j);
	t+="\nislamisches Neujahr (1. Muharram):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(10,1,j);
	t+="\nAschura (10. Muharram):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(11,3,j);
	t+="\nMaulid (Geb. des Propheten Mohammeds, 3. Rabi al-Awwal):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(1,7,j);
	t+="\nBeginn der Drei Heiligen Monate (1. Radjab):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(3,7,j);
	t+="\nRagaib Kandil (3. Radjab):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(27,7,j);
	t+="\nMiradsch Kandil (27. Radjab):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(14,8,j);
	t+="\nBera'at Kandil (14. Schaban):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(27,9,j);
	t+="\nNacht der Macht (Lailat-ul-Qadr, Kadir gecesi, 27. Ramadan):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(1,10,j);
	t+="\nRamadanfest (1. Schawwal):\n        "+getDateStrFromJD(jd,typ);
	var jd=getJDFromIsl(10,12,j);
	t+="\nOpferfest Kurban bayram, Eid-ul-adha (10. Dhu-l-Hidjdja):\n        "+getDateStrFromJD(jd,typ);
	t+="\n\nHinweis: Der Monatsbeginn des islamischen Monats wird manchmal, besonders\n";
	t+="vor hohen Feiertagen von islamischen Instanzen nach der Beobachtung des Neumonds\n";
	t+="bestimmt. Die berechneten Daten können so um ein oder zwei Tage abweichen."; 
	return t;
}


function INT(x){return Math.floor(x);}
