#!/apps/perl/current/bin/perl
#**********************************************************************
# perl/bar_mitzvah_calc.cgi: program to compute bar mitzvah info
#**********************************************************************
use CGI qw/:standard :html3/;
use Time::Local;
#**********************************************************************
# Get current year
#**********************************************************************
$y = (localtime)[5];
if ($y=99){
$z=1900+$y;
} else {
$z=2000+$y;
}
#**********************************************************************
# Civil months in chronological order
#**********************************************************************
@months = qw(
January
February
March
April
May
June
July
August
September
October
November
December
);
#**********************************************************************
# Hash of civil months: number of days
#**********************************************************************
%maxday = qw(
January 31
February 28
March 31
April 30
May 31
June 30
July 31
August 31
September 30
October 31
November 30
December 31
);
#**********************************************************************
# Hebrew months in chronological order
#**********************************************************************
@hmonths = qw(
Tishri
Heshvan
Kislev
Tevet
Shevat
AdarI
AdarII
Nisan
Iyar
Sivan
Tammuz
Av
Elul
);
#**********************************************************************
# Hash of Hebrew months: number of days
#**********************************************************************
%hmaxday = qw(
Tishri 30
Heshvan 30
Kislev 30
Tevet 29
Shevat 30
Adar 29
AdarI 30
AdarII 29
Nisan 30
Iyar 29
Sivan 30
Tammuz 29
Av 30
Elul 29
);
#**********************************************************************
# Print web page header
#**********************************************************************
print header(),
start_html(
-title=>'Bar Mitzvah Calculator',
-bgcolor=>'#191970',
-text=>'#FFFACD'),
h2('Bar Mitzvah Calculator');
#**********************************************************************
# Pick of current state which control which web page was last displayed
#**********************************************************************
$state = param('state');
#**********************************************************************
# If param is not set, this is first time in.
# Display first page which requests birth year ranges.
#**********************************************************************
if (!param()) {
print "Please note: If you were born after sunset on a particular
civil date, be sure to use the following day as your birth day.
";
print hr(), start_form(),
hidden(-name=>'state',-value=>'range',-force=>1),
p("Birth Year Range: ", popup_menu("range",
['1991-'.$z,'1981-1990','1961-1980','1941-1960','1921-1940','1901-1920'])),
p(submit("Continue")),
end_form(), hr();
#**********************************************************************
# If state is "range" this is a return from birth year ranges
# Display second page which requests birth year and birth month
#**********************************************************************
} elsif ($state eq "range") {
$range = param("range");
$byr1 = substr($range,0,4);
$byr2 = substr($range,5,4);
print p("You have chosen year range of: $range ");
print hr(),start_form(),
hidden(-name=>'state',-value=>'year',-force=>1),
"Birth Year: ", popup_menu("byear", [ $byr1..$byr2 ]),
"Birth Month: ", popup_menu("bmon",[@months]),
p(submit("Continue")),
end_form(), hr();
#**********************************************************************
# If state is "year" this is a return from birth year and birth month
# Display third page which requests day of the birth month
#**********************************************************************
} elsif ($state eq "year") {
$byear = param("byear");
$bmon = param("bmon");
if (($byear % 4)== 0){
# print "LEAP YEAR: ";
$maxday{"February"}=29;
# print "Max day for Feb: $maxday{'February'}";
}
$daymax = $maxday{$bmon};
print p("You have chosen: $bmon $byear ");
print hr(),start_form(),
hidden(-name=>'state',-value=>'day',-force=>1),
hidden(-name=>'byear',-value=>$byear,-force=>1),
hidden(-name=>'bmon',-value=>$bmon,-force=>1),
"Day of Birth Month: ", popup_menu("bday", [1...$daymax]),
p(submit("Continue")),
end_form(), hr();
#**********************************************************************
# If state is "day" this is a return from birth year and birth month
# Display fourth page which display all the calculations
#**********************************************************************
} elsif ($state eq "day") {
$byear = param("byear");
$bmon = param("bmon");
$bday = param("bday");
if (($byear % 4)== 0){
# print "LEAP YEAR: ";
$maxday{"February"}=29;
# print "Max day for Feb: $maxday{'February'}";
}
print p("Your civil birthday is $bmon $bday, $byear"),hr();
#***********************************************************************
# Compute day number of the civil year.
#***********************************************************************
$daynum=0;
$i=-1;
do {
$i++;
# print "$i ";
$daynum = $daynum + $maxday{$months[$i]};
# print "$daynum, ";
$tmon=$months[$i];
}until $bmon eq $tmon;
#print "
";
$daynum=$daynum - $maxday{$bmon} + $bday;
#print "$daynum
";
#***********************************************************************
# Read civil year file and obtain Hebrew date
# for January 1 of the chosen year.
#***********************************************************************
open(CIVIL,"Calendar/civref") || die "Could not open civref
";
do {
$_ = ;
if (/$byear/){
($xxxx,$hyear1,$hmon1,$hday1)=split;
# print "yr= $hyear1, mon= $hmon1, day= $hday1
";
}
}until /$byear/;
close(CIVIL);
#***********************************************************************
# Read Hebrew year file to determine the type of year
# and the type of the following year
#***********************************************************************
open(HEBREF,"Calendar/hebref") || die "Could not open hebref
";
$hyear2=$hyear1+1;
do {
$_ = ;
if (/$hyear1/){
# print "$_
";
($yyyy,$hyrtyp1)=split;
# print "Year type1: $hyrtyp1
";
}
if (/$hyear2/){
# print "$_
";
($yyyy,$hyrtyp2)=split;
# print "Year type2: $hyrtyp2
";
}
}until /$hyear2/;
close(HEBREF);
#***********************************************************************
# Read Hebrew type files to determine nature of year and following year.
#***********************************************************************
$type1="Year".$hyrtyp1;
#print "$type1
";
open(TYPE1,"Calendar/$type1") || die "Could not open Yearxx
";
$a=();
chomp($a);
($xxxx,$yyyy,$zzzz,$full1,$leap1)=split(/\s+/,$a);
#print "full1= $full1, leap1= $leap1
";
close(TYPE1);
$type2="Year".$hyrtyp2;
#print "$type2
";
open(TYPE2,"Calendar/$type2") || die "Could not open Yearxx
";
$a=();
chomp($a);
($xxxx,$yyyy,$zzzz,$full2,$leap2)=split(/\s+/,$a);
#print "full2= $full2, leap2= $leap2
";
close(TYPE2);
#***********************************************************************
# Compute number of days in $hyrtyp1 and adjust month lengths
#***********************************************************************
#print "full1: $full1, leap1: $leap1
";
adjust_dates($full1,$leap1);
#print "Number of days in Hebrew year: $hyrdays
";
#***********************************************************************
# Determine what day number of the Hebrew year
# is the Hebrew date for January 1.
#***********************************************************************
$hjan1=0;
$i=-1;
do {
$i++;
# print "$i ";
if ($months[$i] ne "xxxx"){
$hjan1 = $hjan1 + $hmaxday{$hmonths[$i]};
}
# print "$hjan1, ";
$tmon=$hmonths[$i];
}until $hmon1 eq $tmon;
#print "
";
$hjan1=$hjan1 - $hmaxday{$tmon} + $hday1;
#print "$hjan1
";
#***********************************************************************
# Add day of the year to Hebrew date for January 1.
# If past end of Hebrew year,
# subtract number of days in that Hebrew year,
# and adjust dates for next year
#***********************************************************************
$hdaynum=$daynum + $hjan1 - 1;
#print "Hebrew day: $hdaynum
";
#print "hdaynum = $hdaynum, hyrdays = $hyrdays
";
if ($hdaynum > $hyrdays){
# print "Using second year
";
$hyear=$hyear2;
$hdaynum=$hdaynum - $hyrdays;
adjust_dates($full2,$leap2);
} else {
# print "Using first year
";
$hyear=$hyear1;
}
$testday=$hdaynum;
#print "Hebrew day: $hdaynum
";
#***********************************************************************
# Compute the Hebrew birthday for the Hebrew birth year
#***********************************************************************
$i=-1;
do {
$i++;
# print "$i ";
if ($months[$i] ne "xxxx"){
$testday = $testday - $hmaxday{$hmonths[$i]};
}
# print "$testday, ";
}until $testday <= 0;
#print "
";
$testday=$testday + $hmaxday{$hmonths[$i]};
print "The corresponding Hebrew date is $hyear $hmonths[$i] $testday
";
#***********************************************************************
# After Hebrew date is computed, add 13 to the Hebrew year.
#***********************************************************************
$fyear=$hyear + 13;
$fmon_num=i;
$fmonth=$hmonths[$i];
$fday=$testday;
#print "Your Hebrew bar mitzvah date is $fyear $fmonth $fday
";
#***********************************************************************
# Read the new Hebrew Year file for the bar mitzvah year.
#***********************************************************************
open(HEBREF,"Calendar/hebref") || die "Could not open hebref
";
do {
$_=;
if (/$fyear/){
# print "$_
";
($yyyy,$fyrtyp)=split;
# print "Year type: $fyrtyp
";
}
}until /$fyear/;
close(HEBREF);
#***********************************************************************
# Read Hebrew type files to determine nature of the bar mitzvah year.
#***********************************************************************
$type="Year".$fyrtyp;
#print "$type
";
open(TYPE,"Calendar/$type") || die "Could not open Yearxx
";
$_=;
chomp;
($xxxx,$yyyy,$zzzz,$full,$leap)=split;
#print "full= $full, leap= $leap
";
close(TYPE);
#***********************************************************************
# Make adjustment for Cheshven, Kislev and Adar.
#***********************************************************************
#print "fmonth= $fmonth, fday= $fday, full= $full, leap= $leap
";
if ($fday == 30){
if ($fmonth eq "Kislev" && $full eq "Def") {
$fmonth="Tevet";
$fday=1;
}
if ($fmonth eq "Heshvan" && ($full eq "Def" || $full eq "Reg")) {
$fmonth="Kislev";
$fday=1;
}
if ($fmonth eq "AdarI" && $leap eq "Non-leap") {
$fmonth="Nisan";
$fday=1;
}
}
if (($fmonth eq "AdarI" || $fmonth eq "AdarII") && $leap eq "Non-leap") {
$fmonth="Adar";
}
if ($fmonth eq "Adar" && $leap eq "Leap-Year") {
$fmonth="AdarI";
}
#***********************************************************************
# Print the adjusted Hebrew bar mitzvah date.
***********************************************************************
print "Your Hebrew bar mitzvah date is $fyear $fmonth $fday
";
#***********************************************************************
# Adjust the days in the month for the bar mitzvah year.
#***********************************************************************
adjust_dates($full,$leap);
#***********************************************************************
# Determine what day number of the Hebrew year
# is the Hebrew date for the bar mitzvah day.
#***********************************************************************
$fdaynum=0;
$i=-1;
do {
$i++;
# print "$i ";
if ($months[$i] ne "xxxx"){
$fdaynum = $fdaynum + $hmaxday{$hmonths[$i]};
}
# print "$fdaynum, ";
$tmon=$hmonths[$i];
}until $fmonth eq $tmon;
#print "
";
$fdaynum=$fdaynum - $hmaxday{$tmon} + $fday;
#print "Hebrew day of bar mitzvah year: $fdaynum
";
#***********************************************************************
# Determine the civil year by reading the civil reference record
# for the Hebrew bar mitzvah year.
#***********************************************************************
open(CIVIL,"Calendar/civref") || die "Could not open civref
";
do {
$_ = ;
if (/$fyear/){
($cyr,$xxxx,$hmon,$hday)=split;
# print "cyr= $cyr, yr= $fyear, mon= $hmon, day= $hday
";
}
}until /$fyear/;
close(CIVIL);
#***********************************************************************
# Determine what day number of the Hebrew year
# is the Hebrew date for January 1 for the bar mitzvah year.
#***********************************************************************
$fjan1=0;
$i=-1;
do {
$i++;
# print "$i ";
if ($months[$i] ne "xxxx"){
$fjan1 = $fjan1 + $hmaxday{$hmonths[$i]};
}
# print "$fjan1, ";
$tmon=$hmonths[$i];
}until $hmon eq $tmon;
#print "
";
$fjan1=$fjan1 - $hmaxday{$tmon} + $hday;
#print "Hebrew day for Jan. 1 of bar mitzah year: $fjan1
";
#***********************************************************************
# Determine the number of days between the computed date and
# the January 1 date for the computed year.
#***********************************************************************
$numday=$fdaynum-$fjan1+1;
if ($numday >0){
# print "Day number $numday in year $cyr
";
#***********************************************************************
# Adjust February if civil year is a leap year.
#***********************************************************************
if (($cyr % 4)== 0){
# print "LEAP YEAR: ";
$maxday{"February"}=29;
# print "Max day for Feb: $maxday{'February'}";
}
#***********************************************************************
# Determine civil date for bar mitzvah.
#***********************************************************************
$i=-1;
$testday=$numday;
do {
$i++;
# print "$i ";
$testday = $testday - $maxday{$months[$i]};
# print "$testday, ";
}until $testday <= 0;
$testday=$testday + $maxday{$months[$i]};
print "The civil date of your bar mitzvah is $months[$i] $testday, $cyr
";
#***********************************************************************
# Civil date for bar mitzah is in preceding civil year.
# Must count backwards.
#***********************************************************************
} else {
$cyr=$cyr-1;
# print "Day number $numday in year $cyr
";
#***********************************************************************
# Determine civil date for bar mitzvah in preceding civil year.
#***********************************************************************
$i=12;
$testday=$numday;
do {
$i--;
# print "$i ";
$testday = $testday + $maxday{$months[$i]};
# print "$testday, ";
}until $testday > 0;
print "
The civil date of your bar mitzvah is $months[$i] $testday, $cyr
";
}
#***********************************************************************
# Read Hebrew type file a second time to determine determine the sedra.
#***********************************************************************
open(TYPE,"Calendar/$type") || die "Could not open Yearxx
";
do {
$_=;
if (/$fmonth/){
($tmonth,$dddd,@sedra)=split;
}
} until /$fmonth/;
if ($dddd < $fday){
do {
$_=;
($tmonth,$dddd,@sedra)=split;
} until ($tmonth ne $fmonth)||($dddd >= $fday);
}
print p("The corresponding shabbos is $tmonth $dddd
and the sedra is @sedra"),hr();
close(TYPE);
}
print end_html();
#***********************************************************************
# Subroutine -- adjust_dates
#***********************************************************************
sub adjust_dates(){
my($full,$leap)=@_;
if ($full eq "Def"){
$hmaxday{"Heshvan"}=29;
$hmaxday{"Kislev"}=29;
$hyrdays=353;
}elsif ($full eq "Reg"){
$hmaxday{"Heshvan"}=29;
$hmaxday{"Kislev"}=30;
$hyrdays=354;
}elsif ($full eq "Ful"){
$hmaxday{"Heshvan"}=30;
$hmaxday{"Kislev"}=30;
$hyrdays=355;
}
if ($leap eq "Leap-Year"){
$hyrdays=$hyrdays + 30;
$hmonths[5]="AdarI";
$hmonths[6]="AdarII";
}else {
$hmonths[5]="xxxx";
$hmonths[6]="Adar";
}
# print "Date adjustment completed
";
}