Religion-Islam-PrayerTimes-1.02/0040755000000000000000000000000010464212137015213 5ustar rootrootReligion-Islam-PrayerTimes-1.02/MANIFEST0100644002343400234210000000014210463705373017700 0ustar islamwarepsaclnMakefile.PL MANIFEST README t/Religion-Islam-PrayerTimes.t lib/Religion/Islam/PrayerTimes.pm Religion-Islam-PrayerTimes-1.02/lib/0040755000000000000000000000000010464212137015761 5ustar rootrootReligion-Islam-PrayerTimes-1.02/lib/Religion/0040755000000000000000000000000010464212137017531 5ustar rootrootReligion-Islam-PrayerTimes-1.02/lib/Religion/Islam/0040755000000000000000000000000010464212137020576 5ustar rootrootReligion-Islam-PrayerTimes-1.02/lib/Religion/Islam/PrayerTimes.pm0100644002343400234210000014545710464212102024737 0ustar islamwarepsacln#=Copyright Infomation #========================================================== #Module Name : Religion::Islam::PrayerTimes #Program Author : Ahmed Amin Elsheshtawy #Home Page : http://www.islamware.com #Contact Email : support@islamware.com #Copyrights © 2006 IslamWare. All rights reserved. #========================================================== # Original c++ source code version Copyright by Fayez Alhargan, 2001 # This is a module that computes prayer times and sunrise. #========================================================== package Religion::Islam::PrayerTimes; use Carp; use strict; use warnings; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(); our $VERSION = '1.02'; use Math::Complex; use POSIX; use constant{ pi => 4 * atan2(1, 1), # 3.1415926535897932; DToR => (pi / 180), RToH => (12 / pi), EarthRadius => 6378.14 }; my $HStartYear =1420; my $HEndYear = 1450; our @MonthMap = qw(19410 19396 19337 19093 13613 13741 15210 18132 19913 19858 19110 18774 12974 13677 13162 15189 19114 14669 13469 14685 12986 13749 17834 15701 19098 14638 12910 13661 15066 18132 18085 ); our @gmonth = qw(31 31 28 31 30 31 30 31 31 30 31 30 31 31); #makes it circular m[0]=m[12] & m[13]=m[1] our @smonth = qw(31 30 30 30 30 30 29 31 31 31 31 31 31 30); #makes it circular m[0]=m[12] & m[13]=m[1] our %TimeZoneUS = ( AL => -6, AK => -9, AZ => -7, AR => -6, CA => -8, CO => -7, CT => -5, DE => -5, DC => -5, FL => -5, GA => -5, GU => 10, HI => -10, ID => -7, IL => -6, IN => -6, IA => -6, KS => -6, KY => -5, LA => -6, ME => -5, MH => 12, MD => -5, MA => -5, MI => -5, MN => -6, MS => -6, MO => -6, MT => -7, 'NE' => -6, NV => -8, NH => -5, NJ => -5, NM => -7, NY => -5, NC => -5, ND => -6, MP => 10, OH => -5, OK => -6, OR => -8, PA => -5, PR => -4, RI => -5, SC => -5, SD => -6, TN => -5, TX => -6, UT => -7, VT => -5, VI => -4, VA => -5, WA => -5, WV => -5, WI => -6, WY => -7, ); our %TimeZone = ( 'AA'=> -4, 'AC'=>-4, 'AE'=> 4, 'AF'=>4.5, 'AG'=>1, 'AJ'=>4, 'AL'=>1, 'AM'=>4, 'AN'=>1, 'AO'=>1, 'AR'=>-3, #'AS'=>'Australia', #'AT'=>'Ashmore and Cartier Islands', 'AU'=>1, 'AV'=>-4, 'AX'=>-11, 'BA'=>3, 'BB'=>-4, 'BC'=>2, 'BD'=>-4, 'BE'=>1, 'BF'=>-5, 'BG'=>6, 'BH'=>-6, 'BK'=>1, 'BL'=>-4, #'BM'=>'Burma', 'BN'=>1, 'BO'=>2, 'BP'=>11, 'BR'=>'Brazil', #'BS'=>'Bassas da India', 'BT'=>6, 'BU'=>2, #'BV'=>'Bouvet Island', 'BX'=>8, 'BY'=>2, 'CA'=>'Canada', 'CB'=>7, 'CD'=>1, 'CE'=>5.5, 'CF'=>1, 'CG'=>1, 'CH'=>8, 'CI'=>-4, 'CJ'=>-5, 'CK'=>6.5, 'CM'=>1, 'CN'=>3, 'CO'=>-5, #'CR'=>'Coral Sea Islands', 'CS'=>-6, 'CT'=>1, 'CU'=>-5, 'CV'=>-1, #'CW'=>'Avarua', 'CY'=>2, 'DA'=>1, 'DJ'=>3, 'DO'=>-4, 'DR'=>-4, 'EC'=>-5, 'EG'=>2, 'EI'=>0, 'EK'=>1, 'EN'=>2, 'ER'=>3, 'ES'=>-6, 'ET'=>3, #'EU'=>'Europa Island', 'EZ'=>1, 'FG'=>3, 'FI'=>2, 'FJ'=>12, 'FK'=>-4, #'FM'=>'Palikir', 'FO'=>0, #'FP'=>'Clipperton Island', 'FR'=>1, #'FS'=>'French Southern and Antarctic Lands', 'GA'=>0, 'GB'=>1, 'GG'=>4, 'GH'=>0, 'GI'=>1, 'GJ'=>-4, 'GK'=>0, 'GL'=>-3, 'GM'=>1, #'GO'=>'Glorioso Islands', 'GP'=>-4, 'GR'=>2, 'GT'=>-6, 'GU'=>1, 'GV'=>0, 'GY'=>-4, 'GZ'=>2, 'HA'=>-5, 'HK'=>8, #'HM'=>'Heard Island and McDonald Islands', 'HO'=>-6, 'HR'=>1, 'HU'=>1, 'IC'=>0, #Indonesia Centeral 'ID'=>8, #Indonesia East 'ID1'=>9, #Indonesia West 'ID2'=>7, #'IM'=>'Isle of Man', 'IN'=>5.5, #'IO'=>'British Indian Ocean Territory', #'IP'=>'Clipperton Island', 'IR'=>3.5, 'IS'=>2, 'IT'=>1, 'IV'=>0, 'IZ'=>3, 'JA'=>9, 'JE'=>0, 'JM'=>-5, 'JN'=>1, 'JO'=>2, #'JU'=>'Juan de Nova Island', 'KE'=>3, 'KG'=>5, 'KN'=>9, 'KR'=>12, 'KS'=>9, 'KT'=>-10, 'KU'=>3, 'KZ'=>6, 'LA'=>7, 'LE'=>2, 'LG'=>2, 'LH'=>2, 'LI'=>0, 'LO'=>1, 'LS'=>1, 'LT'=>2, 'LU'=>1, 'LY'=>2, 'MA'=>3, 'MB'=>-4, #'MC'=>'Macau', 'MD'=>2, 'MF'=>3, 'MG'=>8, 'MH'=>-4, 'MI'=>2, 'MK'=>1, 'ML'=>0, 'MN'=>1, 'MO'=>0, 'MP'=>4, 'MR'=>0, 'MT'=>1, 'MU'=>4, 'MV'=>5, 'MX'=>'Mexico', 'MY'=>8, 'MZ'=>2, 'NC'=>11, #'NE'=>'Alofi', 'NF'=>11.5, 'NG'=>1, 'NH'=>11, 'NI'=>1, 'NL'=>1, #'NM'=>'No Man\'s Land', 'NO'=>1, 'NP'=>7.75, 'NR'=>12, 'NS'=>-3, 'NT'=>-4, 'NU'=>-6, 'NZ'=>12, 'PA'=>-4, #'PC'=>'Adamstown', 'PE'=>-5, 'PK'=>5, 'PL'=>1, 'PM'=>-5, 'PO'=>0, 'PP'=>10, 'PR'=>-4, 'PU'=>0, 'QA'=>3, 'RE'=>4, #'RM'=>'Majuro', 'RO'=>2, 'RP'=>8, #'RS'=>'Russia', 'RS1'=>2, 'RS2'=>4, 'RS3'=>4, 'RS4'=>5, 'RS5'=>6, 'RS6'=>7, 'RS7'=>8, 'RS8'=>9, 'RS9'=>10, 'RS10'=>11, 'RS11'=>12, 'RW'=>2, 'SA'=>3, 'SB'=>-3, 'SC'=>-4, 'SE'=>4, 'SF'=>2, 'SG'=>0, #'SH'=>'Jamestown', 'SI'=>1, 'SL'=>0, 'SM'=>1, 'SN'=>8, 'SO'=>3, 'SP'=>1, 'ST'=>-4, 'SU'=>2, #'SV'=>'Svalbard', 'SW'=>1, #'SX'=>'South Georgia and the South Sandwich Islands', 'SY'=>2, 'SZ'=>1, 'TD'=>-4, #'TE'=>'Tromelin Island', 'TH'=>7, 'TI'=>6, 'TK'=>-5, #'TL'=>'Tokelau', 'TN'=>13, 'TO'=>0, 'TP'=>0, 'TS'=>1, #'TT'=>'East Timor', 'TU'=>2, 'TV'=>12, 'TW'=>8, 'TX'=>5, 'TZ'=>3, 'UG'=>3, 'UK'=>0, 'UP'=>2, #'US'=>'United States', 'UV'=>0, 'UY'=>-3, 'UZ'=>5, 'VC'=>-4, 'VE'=>-4, 'VI'=>-4, 'VM'=>7, 'VT'=>1, 'WA'=>1, 'WE'=>2, 'WF'=>12, 'WI'=>0, 'WS'=>-11, 'WZ'=>2, 'YI'=>1, 'YM'=>3, 'ZA'=>2, 'ZI'=>2 ); #========================================================== #========================================================== sub new { my ($class, %args) = @_; my $self = bless {}, $class; # Defaults $self->{JuristicMethod} = 1; # Standard $self->CalculationMethod(3); # Egyptian General Authority of Survey $self->{SafetyTime} = 0.016388; # 59 seconds, safety time $self->{ReferenceAngle} = 45; $self->{EidPrayerTime} = 4.2; # Eid Prayer Time 4.2 $self->{DaylightSaving} = 0; # Cairo as the default location $self->{Latitude} = 30.050; $self->{Longitude} = 31.250; $self->{Altitude} = 22; $self->{TimeZone} = 2; $self->{TimeMode} = 0; # 12 or 24 hour time format my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon++; $year += 1900; return $self; } #========================================================== # Safety time in hours should be 0.016383h. 59seconds, safety time sub SafetyTime { my ($self) = shift; $self->{SafetyTime} = shift if @_; return $self->{SafetyTime}; } #========================================================== #Juristic Methods: # 1)-Standard (Imams Shafii, Hanbali, and Maliki), # 2)-Hanafi #Aser = 1 or 2 #The Henfy (asr=2), Shafi (asr=1, Omalqrah asr=1) sub JuristicMethod { my ($self, $method) = @_; if (!defined $method || int($method) < 1 || int($method) > 2) { return $self->{JuristicMethod}; } $self->{JuristicMethod} = $method; return $self->{JuristicMethod}; } #========================================================== # Calculation Method #1: Umm Al-Qura Committee #2: Muslim World League #3: Egyptian General Authority of Survey #4: University Of Islamic Sciences, Karachi #5: ISNA, Islamic Society of North America sub CalculationMethod { my ($self, $method) = @_; if (!defined $method || int($method) < 1 || int($method) > 5) { return $self->{CalculationMethod}; } $self->{CalculationMethod} = $method; if ($method == 1) {# Umm Al-Qura Committee $self->{FajerAngle} = 19; $self->{IshaAngle} = 0; $self->{IshaFixedTime} = 1.5; } elsif ($method == 2) {# Muslim World League $self->{FajerAngle} = 18; $self->{IshaAngle} = 17; $self->{IshaFixedTime} = 1.5; } elsif ($method == 3) {# Egyptian General Authority of Survey $self->{FajerAngle} = 19.5; $self->{IshaAngle} = 17.5; $self->{IshaFixedTime} = 1.5; } elsif ($method == 4) { # University Of Islamic Sciences, Karachi $self->{FajerAngle} = 18; $self->{IshaAngle} = 18; $self->{IshaFixedTime} = 1.5; } elsif ($method == 5) { # ISNA, Islamic Society of North America $self->{FajerAngle} = 15; $self->{IshaAngle} = 15; $self->{IshaFixedTime} = 1.5; } return $self->{CalculationMethod}; } #========================================================== sub FajerAngle{ my ($self) = shift; $self->{FajerAngle} = shift if @_; return $self->{FajerAngle}; } #========================================================== sub IshaAngle{ my ($self) = shift; $self->{IshaAngle} = shift if @_; return $self->{IshaAngle}; } #========================================================== sub IshaFixedTime{ my ($self) = shift; $self->{IshaFixedTime} = shift if @_; return $self->{IshaFixedTime}; } #========================================================== #Reference Angle suggested by Rabita 45 #latude (radian) that should be used for places above -+65.5 should be 45deg as suggested by Rabita sub ReferenceAngle{ my ($self) = shift; $self->{ReferenceAngle} = shift if @_; return $self->{ReferenceAngle}; } #========================================================== # Eid Prayer Time 4.2 sub EidPrayerTime{ my ($self) = shift; $self->{EidPrayerTime} = shift if @_; return $self->{EidPrayerTime}; } #========================================================== # Longitude in radians sub Longitude{ my ($self) = shift; $self->{Longitude} = shift if @_; return $self->{Longitude}; } #========================================================== # Latitude in radians sub Latitude { my ($self) = shift; $self->{Latitude} = shift if @_; return $self->{Latitude}; } #========================================================== # HeightdifW : param[3]: The place western herizon height difference in meters # HeightdifE : param[4]: The place eastern herizon height difference in meters sub Altitude{ my ($self) = shift; $self->{Altitude} = shift if @_; return $self->{Altitude}; } #========================================================== # Time Zone difference from GMT sub TimeZone{ my ($self) = shift; $self->{TimeZone} = shift if @_; return $self->{TimeZone}; } #========================================================== # Q. What is daylight saving? Ans. Many countries try to adopt their work time by subtracting # from their clocks one hour in the Fall and Winter seasons. sub DaylightSaving { my ($self) = shift; my ($time); if (@_) { $time = shift; if ($time > 0) { $self->{DaylightSaving} = 1; } else {$self->{DaylightSaving} = 0;} } return $self->{DaylightSaving}; } #========================================================== sub TimeMode { my ($self, $mode) = @_; if (!defined $mode) { return $self->{TimeMode}; } $mode = $mode ? 1: 0; $self->{TimeMode} = $mode; return $self->{TimeMode}; } #========================================================== sub FormatTime{ my ($self, $time) = @_; my ($hour, $min, $sec, $am); $hour = int ($time); $min = int (60.0*($time- $hour)); if ($min == 60) {$hour++; $min = 0;} if ($min < 0) {$min = -$min;} $min = sprintf("%02d", $min); $hour = sprintf("%02d", $hour); if (!$self->{TimeMode}) { # 12 hour mode $am = ($hour > 12)? 'pm': 'am'; if ($hour >12) {$hour -= 12;} } else { $am = ""; } return ($hour, $min, $am); } #========================================================== sub GregorianMonthLength { my ($self, $month, $year) = @_; # Compute the last date of the month for the Gregorian calendar. if ($month == 2) { return 29 if ($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0); } return (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[$month - 1]; } #========================================================== sub IslamicLeapYear { my ($self, $year) = @_; # True if year is an Islamic leap year return ((((11 * $year) + 14) % 30) < 11) ? 1 : 0; } #========================================================== sub IslamicMonthLength { my ($self, $month, $year) = @_; # Last day in month during year on the Islamic calendar. return ($month % 2 == 1) || ($month == 12 && IslamicLeapYear($year)) ? 30 : 29; } #========================================================== #Set the prayer location to calculate for. sub PrayerLocation { my ($self, %args) = @_; $self->{Latitude} = $args{Latitude}; # Latitude $self->{Longitude} = $args{Longitude}; # Longitude $self->{Altitude} = $args{Altitude}; #HeightdifW : param[3]: The place western herizon height difference in meters $self->{TimeZone} = $args{TimeZone}; # Time Zone difference from GMT my $key; my $value; #while (($key, $value)=each(%args)) {print ("PrayerLocation: $key = $value\n");} } #========================================================== #=PrayerTimes # For international prayer times see Islamic Fiqah Council of the Muslim # World League: Saturday 12 Rajeb 1406H, concerning prayer times and fasting # times for countries of high latitudes. # This program is based on the above. # # Arguments: # yg, mg, dg : Date in Greg # param[0] : Safety time in hours should be 0.016383h # longtud,latud : param[1],[2] : The place longtude and latitude in radians # HeightdifW : param[3]: The place western herizon height difference in meters # HeightdifE : param[4]: The place eastern herizon height difference in meters # Zonh :param[5]: The place zone time dif. from GMT West neg and East pos in decimal hours # fjrangl : param[6]: The angle (radian) used to compute Fajer prayer time (OmAlqrah -19 deg.) # ashangl : param[7]: The angle (radian) used to compute Isha prayer time # ashangl=0 then use (OmAlqrah: ash=SunSet+1.5h) # asr : param[8]: The Henfy (asr=2) Shafi (asr=1, Omalqrah asr=1) # param[9] : latude (radian) that should be used for places above -+65.5 should be 45deg as suggested by Rabita # param[10] : The Isha fixed time from Sunset # # Output: # lst[]...lst[n], # 1: Fajer # 2: Sunrise # 3: Zohar # 4: Aser # 5: Magreb # 6: Isha # 7: Fajer using exact Rabita method for places >48 # 8: Ash using exact Rabita method for places >48 # 9: Eid Prayer Time # for places above 48 lst[1] and lst[6] use a modified version of # Rabita method that tries to eliminate the discontinuity # all in 24 decimal hours # #returns flag :0 if there are problems, flag:1 no problems #=cut # Compute prayer times and sunrise sub PrayerTimes { my ($self, $yg, $mg, $dg) = @_; my (@lst, @param, %result); #print "PrayerTimes for : $yg, $mg, $dg \n\n"; $param[0] = $self->{SafetyTime}; # 59seconds, safety time $param[1] = $self->{Longitude}*DToR; # Longitude in radians $param[2] = $self->{Latitude}*DToR; # Latitude in radians $param[3] = $self->{Altitude}; #HeightdifW : param[3]: The place western herizon height difference in meters $param[4] = $self->{Altitude}; #HeightdifE : param[4]: The place eastern herizon height difference in meters $param[5] = $self->{TimeZone}; # Time Zone difference from GMT $param[6] = $self->{FajerAngle}*DToR; # Fajer Angle =19 $param[7] = $self->{IshaAngle}*DToR; # Isha Angle if set to zero, then $param[10] must be 1.5 $param[8] = $self->{JuristicMethod}; #Aser=1, 2, Juristic Methods: Standard and Hanafi $param[9] = $self->{ReferenceAngle}*DToR; # Reference Angle suggested by Rabita 45 $param[10] = $self->{IshaFixedTime}; # Isha fixed time from sunset =1.5, if $param[7] > 0 then this is discarded $param[11] = $self->{EidPrayerTime}*DToR; # Eid Prayer Time 4.2 # $param[0]= 0.016388; # /* 59seconds, safety time */ # $param[1]=$longtud*DToR; #/* Longitude in radians */ # $param[2]=$latud*DToR; # $param[3]=22.0; # $param[4]=22.0; # $param[5]=$Zonh; # /* Time Zone difference from GMT S.A. 2*/ # $param[6]=19.5*DToR; #/* Fajer Angle =19 */ # $param[7]=17.5*DToR; #/* Isha Angle if setto zero, then $param[10] must be 1.5*/ # $param[8]=1; #/* Aser=1,2 OmAlrqah Aser=1*/ # $param[9]=45*DToR; #/* Reference Angle suggested by Rabita 45*/ # $param[10]=1.5; #/* Isha fixed time from sunset =1.5, if $param[7] >0 then this is discarded*/ # $param[11]=4.2*DToR; #/* Eid Prayer Time 4.2 */ # for my $xx(0..$#param) { # print "Param: $xx = ". $param[$xx] . "\n"; # } my $flag=1; my $flagrs; my $problm=0; my ($RA, $Decl); my ($Rise, $Transit, $Setting); my ($SINd, $COSd); my ($act, $H, $angl, $K, $cH); my ($X, $MaxLat); my ($H0, $Night, $IshRt, $FajrRt); my $HightCorWest=0; my $HightCorEast=0; my ($IshFix, $FajrFix); my $JD; #Main Local variables: #RA= Sun's right ascension #Decl= Sun's declination #H= Hour Angle for the Sun #K= Noon time #angl= The Sun altitude for the required time #flagrs: sunrise sunset flags # 0:no problem # 16: Sun always above horizon (at the ploes for some days in the year) # 32: Sun always below horizon # Compute the Sun various Parameters ($JD, $Rise, $Transit, $Setting, $RA, $Decl, $flagrs) = $self->SunParamr($yg, $mg, $dg, -$param[1], $param[2], -$param[5]); # Compute General Values $SINd=sin($Decl)*sin($param[2]); $COSd=cos($Decl)*cos($param[2]); # Noon $K=$Transit; # Compute the height correction $HightCorWest=0; $HightCorEast=0; if ($flagrs==0 && fabs($param[2])<0.79 && ($param[4]!=0 || $param[3]!=0)) { # height correction not used for problematic places above 45deg $H0=$H=0; $angl=-0.83333*DToR; # standard value angl=50min=0.8333deg for sunset and sunrise $cH=(sin($angl)-$SINd)/($COSd); $H0=acos($cH); $X= EarthRadius*1000.0; # meters $angl = -0.83333*DToR+(0.5*pi - asin($X/($X+$param[3]))); $cH=(sin($angl)-$SINd)/($COSd); $HightCorWest=acos($cH); $HightCorWest=($H0-$HightCorWest)*(RToH); $angl=-0.83333*DToR+(0.5*pi-asin($X/($X+$param[4]))); $cH=(sin($angl)-$SINd)/($COSd); $HightCorEast=acos($cH); $HightCorEast=($H0-$HightCorEast)*(RToH); } # Modify Sunrise,Sunset and Transit for problematic places if (!($flagrs==0 && fabs($Setting-$Rise)>1 && fabs($Setting-$Rise)<23)) { # There are problems in computing sun(rise,set) # This is because of places above -+65.5 at some days of the year #Note param[9] should be 45deg as suggested by Rabita $problm=1; if ($param[2]<0) {$MaxLat= -fabs($param[9]);} else {$MaxLat= fabs($param[9]);} #Recompute the Sun various Parameters using the reference param[9] #($JD, $Rise, $Transit, $Setting, $RA, $Decl, $RiseSetFlags) my ($JD, $Rise, $Transit, $Setting, $RA, $Decl, $flagrs) = $self->SunParamr($yg, $mg, $dg, -$param[1], $MaxLat, -$param[5]); $K = $Transit; # exact noon time #ReCompute General Values for the new reference param[9] $SINd=sin($Decl)*sin($MaxLat); $COSd=cos($Decl)*cos($MaxLat); } #------------------------------------------------------------- if($K<0) {$K=$K+24;} #print "[$Rise - $HightCorEast, K=$K] \n"; $lst[2]=$Rise-$HightCorEast; # Sunrise - Height correction $lst[3]= $K+ $param[0]; # Zohar time+extra time to make sure that the sun has moved from zaowal $lst[5]= $Setting+$HightCorWest+ $param[0]; #Magrib= SunSet + Height correction + Safety Time #------------------------------------------------------------- # Asr time: Henfy param[8]=2, Shafi param[8]=1, OmAlqrah asr=1 if($problm){# For places above 65deg $act=$param[8]+tan(fabs($Decl-$MaxLat)); } else {#no problem $act=$param[8]+tan(fabs($Decl-$param[2])); # In the standard equations abs() is not used, but it is required for -ve latitude } $angl=atan(1.0/$act); $cH=(sin($angl)-$SINd)/($COSd); if(fabs($cH)>1.0) { $H=3.5; $flag=0; #problem in compuing Asr } else { $H=acos($cH); $H=$H*RToH; } $lst[4]=$K+$H+$param[0]; # Asr Time #------------------------------------------------------------- #Fajr Time $angl= -$param[6]; # The value -19deg is used by OmAlqrah for Fajr, but it is not correct, Astronomical twilight and Rabita use -18deg $cH=(sin($angl)-$SINd)/($COSd); if (fabs($param[2])<0.83776){# If latitude<48deg # no problem $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[1]=$K-($H+$HightCorEast)+$param[0]; #Fajr time $lst[7]=$lst[1]; } else { # Get fixed ratio, data depends on latitutde sign if($param[2]<0){ my ($IshFix, $FajrFix) = $self->GetRatior($yg, 12, 21, @param); } else{ my ($IshFix, $FajrFix) = $self->GetRatior($yg, 6, 21, @param); } if (fabs($cH)>(0.45+1.3369*$param[6]))# A linear equation I have interoduced { # The problem occurs for places above -+48 in the summer $Night = 24-($Setting-$Rise);# Night Length $lst[1]=$Rise-$Night*$FajrFix; #According to the general ratio rule } else { # no problem $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[1]=$K-($H+$HightCorEast)+$param[0]; # Fajr time } $lst[7]=$lst[1]; if (fabs($cH)>1) { # The problem occurs for places above -+48 in the summer my ($IshRt, $FajrRt) = $self->GetRatior($yg, $mg, $dg, @param); $Night=24-($Setting-$Rise); #Night Length $lst[7]= $Rise-$Night*$FajrRt; # Accoording to Rabita Method } else { # no problem $H = acos($cH); $H= $H*RToH; #convert radians to hours $lst[7] = $K- ($H+$HightCorEast)+$param[0]; #Fajr time } } #------------------------------------------------------------- # Isha prayer time if($param[7]!=0) # if Ish angle not equal zero { $angl= -$param[7]; $cH=(sin($angl)-$SINd)/($COSd); if (fabs($param[2])<0.83776) # If latitude<48deg { #no problem $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[6]=$K+($H+$HightCorWest+$param[0]); #Isha time, instead of Sunset+1.5h $lst[8]=$lst[6]; } else { if (fabs($cH)>(0.45+1.3369*$param[6])) # A linear equation I have interoduced { #The problem occurs for places above -+48 in the summer $Night=24-($Setting-$Rise); # Night Length $lst[6]=$Setting+$Night*$IshFix; # Accoording to Rabita Method } else { #no problem $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[6]=$K+($H+$HightCorWest+$param[0]); # Isha time, instead of Sunset+1.5h } if (fabs($cH)>1.0) { #The problem occurs for places above -+48 in the summer my ($IshRt, $FajrRt) = $self->GetRatior($yg, $mg, $dg, @param); $Night=24-($Setting-$Rise); #Night Length $lst[8]=$Setting+$Night*$IshRt; #According to the general ratio rule } else { $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[8]=$K+($H+$HightCorWest+$param[0]); # Isha time, instead of Sunset+1.5h } } } else { $lst[6]=$lst[5]+$param[10]; #Isha time OmAlqrah standard Sunset+fixed time (1.5h or 2h in Romadan) $lst[8]=$lst[6]; } # ------------------------------------------------------------- # Eid prayer time $angl=$param[11]; # Eid Prayer time Angle is 4.2 $cH=(sin($angl)-$SINd)/($COSd); if ((fabs($param[2])<1.134 || $flagrs==0) && fabs($cH)<=1.0)# If latitude<65deg {# no problem $H=acos($cH); $H=$H*RToH; #convert radians to hours $lst[9]=$K-($H+$HightCorEast)+$param[0];# Eid time } else { $lst[9]=$lst[2]+0.25; #If no Sunrise add 15 minutes } #--------------------------------------------- # return the result in a hash undef %result; $result{Flag} = $flag; # flag =0: means problem in compuing Asr $result{Fajr} = $lst[1] + $self->{DaylightSaving}; $result{Sunrise} = $lst[2] + $self->{DaylightSaving}; $result{Zohar} = $lst[3] + $self->{DaylightSaving}; $result{Aser} = $lst[4] + $self->{DaylightSaving}; $result{Maghrib} = $lst[5] + $self->{DaylightSaving}; $result{Isha} = $lst[6] + $self->{DaylightSaving}; $result{FajirRabita} = $lst[7] + $self->{DaylightSaving}; #Fajer using exact Rabita method for places >48 $result{IshaRabita} = $lst[8] + $self->{DaylightSaving}; #Ash using exact Rabita method for places >48 $result{Eid} = $lst[9] + $self->{DaylightSaving}; #Eid Prayer Time #for places above 48 lst[1] and lst[6] use a modified version of #Rabita method that tries to eliminate the discontinuity #all in 24 decimal hours return %result; } #========================================================== sub atanxy{ my ($self, $x, $y) = @_; my $argm; if ($x==0) {$argm=0.5*pi;} else {$argm=atan($y/$x);} if ($x>0 && $y<0) {$argm=2.0*pi+$argm;} if ($x<0) {$argm=pi+$argm;} return $argm; } #========================================================== #========================================================== # EclipToEquator(tht , 0, *RA,*Decl); sub EclipToEquator{ my ($self, $lmdr, $betar) = @_; my ($alph, $dltr); # Convert Ecliptic to Equatorial Coordinate # p.40 No.27, Peter Duffett-Smith book # input: lmdr,betar in radians # output: alph,dltr in radians my $eps = 23.441884; # (in degrees) this changes with time my ($sdlt, $epsr); my ($x, $y, $alpr); my $rad = 0.017453292; # =pi/180.0 $epsr = $eps * $rad; # convert to radians $sdlt = sin($betar)*cos($epsr)+cos($betar)*sin($epsr)*sin($lmdr); $dltr = asin($sdlt); $y = sin($lmdr)*cos($epsr)-tan($betar)*sin($epsr); $x = cos($lmdr); $alph = $self->atanxy($x, $y); return ($alph, $dltr); } #========================================================== sub RoutinR2{ my ($self, $M, $e) = @_; # Routine R2: # Calculate the value of E # p.91, Peter Duffett-Smith book my $dt=1; my ($dE, $Ec); $Ec = $M; while (fabs($dt)>1e-9) { $dt = $Ec - $e*sin($Ec)-$M; $dE = $dt/(1-$e*cos($Ec)); $Ec = $Ec - $dE; } return $Ec; } #========================================================== # p.99 of the Peter Duffett-Smith book sub SunParamr{ my ($self, $yg, $mg, $dg, $ObsLon, $ObsLat, $TimeZone)=@_; my ( $Rise, $Transit, $Setting, $RA, $Decl, $RiseSetFlags); my ($UT, $ET, $y, $L, $e, $M, $omg); my ($eps, $T, $JD, $Ec); my ($tnv, $v, $tht); my ($K, $angl, $T1, $T2, $H, $cH); $RiseSetFlags = 0; $JD = $self->GCalendarToJD($yg, $mg, $dg); $T = ($JD + $TimeZone/24.0 - 2451545.0) / 36525.0; $L = 279.6966778+36000.76892*$T + 0.0003025*$T*$T; # in degrees while ($L > 360) {$L = $L-360;} while ($L < 0) {$L = $L+360;} $L = $L*pi/180.0; # radians $M = 358.47583+35999.04975*$T-0.00015*$T*$T-0.0000033*$T*$T*$T; while ($M>360) {$M=$M-360;} while ($M<0) {$M=$M+360;} $M = $M*pi/180.0; $e=0.01675104-0.0000418*$T-0.000000126*$T*$T; $Ec=23.452294-0.0130125*$T-0.00000164*$T*$T+0.000000503*$T*$T*$T; $Ec=$Ec*pi/180.0; $y=tan(0.5*$Ec); $y=$y*$y; $ET=$y*sin(2*$L)-2*$e*sin($M)+4*$e*$y*sin($M)*cos(2*$L)-0.5*$y*$y*sin(4*$L)-5*0.25*$e*$e*sin(2*$M); $UT=$ET*180.0/(15.0*pi); # from radians to hours $Ec = $self->RoutinR2($M, $e); $tnv = sqrt((1+$e)/(1-$e))*tan(0.5*$Ec); $v = 2.0*atan($tnv); $tht = $L+$v-$M; ($RA, $Decl) = $self->EclipToEquator($tht,0); $K = 12-$UT-$TimeZone+$ObsLon*12.0/pi; # (Noon) $Transit = $K; # Sunrise and Sunset $angl = (-0.833333)*DToR; # Meeus p.98 $T1=(sin($angl)-sin($Decl)*sin($ObsLat)); $T2=(cos($Decl)*cos($ObsLat)); # p.38 Hour angle for the Sun $cH=$T1/$T2; if ($cH>1) {$RiseSetFlags = 16; $cH=1;} #At this day and place the sun does not rise or set $H = acos($cH); $H = $H*12.0/pi; $Rise = $K-$H; # Sunrise $Setting = $K+$H; # SunSet return ($JD, $Rise, $Transit, $Setting, $RA, $Decl, $RiseSetFlags); } #========================================================== # Function to obtain the ratio of the start time of Isha and Fajr at # a referenced latitude (45deg suggested by Rabita) to the night length # void GetRatior(int yg,int mg,int dg,double param[],double *IshRt,double *FajrRt) # ($IshFix, $FajrFix) = &GetRatior($yg, 12, 21, @param); sub GetRatior{ my ($self, $yg, $mg, $dg, @param)=@_; my ($IshRt, $FajrRt); my $flagrs; my ($RA, $Decl); my ($Rise,$Transit, $Setting); my ($SINd, $COSd); my ($H, $angl, $cH); my ($MaxLat); my ($FjrRf, $IshRf); my ($Night); if ($param[2]<0) {$MaxLat= -fabs($param[9]);} else {$MaxLat= fabs($param[9]);} ($Rise, $Transit, $Setting, $RA, $Decl, $flagrs) = $self->SunParamr($yg, $mg, $dg, -$param[1], $MaxLat, -$param[5]); $SINd=sin($Decl)*sin($MaxLat); $COSd=cos($Decl)*cos($MaxLat); $Night=24-($Setting-$Rise); #Night Length #Fajr $angl= -$param[6]; $cH=(sin($angl)-$SINd)/($COSd); $H=acos($cH); $H=$H*RToH; # convert radians to hours $FjrRf=$Transit-$H-$param[0]; #Fajr time #Isha if ($param[7]!=0) #if Ish angle not equal zero { $angl= -$param[7]; $cH=(sin($angl)-$SINd)/($COSd); $H=acos($cH); $H=$H*RToH; #convert radians to hours $IshRf=$Transit+$H+$param[0];# Isha time, instead of Sunset+1.5h } else { $IshRf=$Setting+$param[10]; #Isha time OmAlqrah standard Sunset+1.5h } $IshRt= ($IshRf-$Setting)/$Night; #Isha time ratio $FajrRt=($Rise-$FjrRf)/$Night; #Fajr time ratio return ($IshRt, $FajrRt); } #========================================================== =BH2GA Name: BH2GA Type: Procedure Purpose: Finds Gdate(year,month,day) for Hdate(year,month,day=1) Arguments: Input: Hijrah date: year:yh, month:mh Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek and returns flag found:1 not found:0 =cut # ($yg1, $mg1, $dg1, $dw2) = &BH2GA($yh2,$mh2); sub BH2GA{ my ($self, $yh, $mh) = @_; my ($yg, $mg, $dg, $dayweek); my ($flag, $Dy, $m, $b); my ($JD); my ($GJD); #Make sure that the date is within the range of the tables if ($mh<1) {$mh=12;} if ($mh>12) {$mh=1;} if ($yh<$HStartYear) {$yh=$HStartYear;} if ($yh>$HEndYear) {$yh=$HEndYear;} $GJD = $self->HCalendarToJDA($yh,$mh,1); (undef, $yg, $mg, $dg) = $self->JDToGCalendar($GJD); $JD=$GJD; $dayweek=($JD+1)%7; $flag=1; #date has been found return ($flag, $yg, $mg, $dg, $dayweek); } #========================================================== =HCalendarToJDA Name: HCalendarToJDA Type: Function Purpose: convert Hdate(year,month,day) to Exact Julian Day Arguments: Input : Hijrah date: year:yh, month:mh, day:dh Output: The Exact Julian Day: JD =cut # $GJD= &HCalendarToJDA($yh,$mh,1); sub HCalendarToJDA{ my ($self, $yh, $mh, $dh) = @_; my ($flag, $Dy, $m, $b); my ($JD); my ($GJD); $JD = int ($self->HCalendarToJD($yh,1,1));# estimate JD of the begining of the year $Dy = int ($MonthMap[$yh-$HStartYear]/4096); # Mask 1111000000000000 $GJD=$JD-3+$Dy; #correct the JD value from stored tables $b = int ($MonthMap[$yh-$HStartYear]); $b=int ($b-$Dy*4096); for ($m=1; $m<$mh; $m++) { $flag = $b % 2; #Mask for the current month if ($flag) {$Dy=30;} else {$Dy=29;} $GJD=$GJD+$Dy; #Add the months lengths before mh $b=int (($b-$flag)/2); } $GJD=$GJD+$dh-1; return $GJD; } #========================================================== =HMonthLength Name: HMonthLength Type: Function Purpose: Obtains the month length Arguments: Input : Hijrah date: year:yh, month:mh Output: Month Length int HMonthLength(int yh,int mh) =cut sub HMonthLength{ my ($self, $yh, $mh) = @_; my ($flag, $Dy, $N, $m, $b); if ($yh<$HStartYear || $yh>$HEndYear) { $flag=0; $Dy=0; } else { $Dy=int ($MonthMap[$yh-$HStartYear]/4096); # Mask 1111000000000000 $b=int($MonthMap[$yh-$HStartYear]); $b=int($b-$Dy*4096); for($m=1;$m<=$mh;$m++) { $flag = $b % 2; #Mask for the current month if ($flag) {$Dy=30;} else {$Dy=29;} $b=int(($b-$flag)/2); } } return $Dy; } #========================================================== =DayInYear Name: DayInYear Type: Function Purpose: Obtains the day number in the yea Arguments: Input : Hijrah date: year:yh, month:mh day:dh Output: Day number in the Year int DayinYear(int yh,int mh,int dh) =cut sub DayinYear{ my ($self, $yh, $mh, $dh) = @_; my ($flag, $Dy, $N, $m, $b, $DL); if ($yh<$HStartYear || $yh>$HEndYear) { $flag=0; $DL=0; } else { $Dy=int($MonthMap[$yh-$HStartYear]/4096); # Mask 1111000000000000 $b=int($MonthMap[$yh-$HStartYear]); $b=int($b-$Dy*4096); $DL=0; for ($m=1; $m<=$mh; $m++) { $flag = $b % 2; #Mask for the current month if ($flag) {$Dy=30;} else {$Dy=29;} $b=int(($b-$flag)/2); $DL=int($DL+$Dy); } $DL=int($DL+$dh); } return $DL; } #========================================================== =HYearLength Name: HYearLength Type: Function Purpose: Obtains the year length Arguments: Input : Hijrah date: year:yh Output: Year Length int HYearLength(int yh) =cut sub HYearLength{ my ($self, $yh) = @_; my ($flag, $Dy, $N, $m, $b, $YL); if ($yh<$HStartYear || $yh>$HEndYear) { $flag=0; $YL=0; } else { $Dy=int($MonthMap[$yh-$HStartYear]/4096); #Mask 1111000000000000 $b=int($MonthMap[$yh-$HStartYear]); $b=int($b-$Dy*4096); $flag=$b % 2; #Mask for the current month if ($flag) {$YL=30;} else {$YL=29;} for ($m=2; $m<=12; $m++) { $flag = $b % 2; # Mask for the current month if ($flag) {$Dy=30;} else {$Dy=29;} $b=int(($b-$flag)/2); $YL=int($YL+$Dy); } } return $YL; } #========================================================== =G2HA Name: G2HA Type: Procedure Purpose: convert Gdate(year,month,day) to Hdate(year,month,day) Arguments: Input: Gregorian date: year:yg, month:mg, day:dg Output: Hijrah date: year:yh, month:mh, day:dh, day of week:dayweek and returns flag found:1 not found:0 int G2HA(int yg,int mg, int dg,int *yh,int *mh,int *dh,int *dayweek) =cut sub G2HA{ my ($self, $yg, $mg, $dg) = @_; my ($yh, $mh, $dh, $dayweek); my ($yh1, $mh1, $dh1); my ($yh2, $mh2, $dh2); my ($yg1, $mg1, $dg1); my ($yg2, $mg2, $dg2); my ($df, $dw2); my ($flag); my ($J); my ($GJD, $HJD); $GJD = $self->GCalendarToJD($yg, $mg, $dg+0.5); # find JD of Gdate ($yh1,$mh1, $dh1) = $self->JDToHCalendar($GJD); # estimate the Hdate that correspond to the Gdate $HJD = $self->HCalendarToJDA($yh1, $mh1, $dh1); #// get the exact Julian Day $df=int ($GJD-$HJD); $dh1=int($dh1+$df); while ($dh1>30) { $dh1=int($dh1-$self->HMonthLength($yh1, $mh1)); $mh1++; if ($mh1>12) {$yh1++; $mh1=1;} } if ($dh1==30) { $mh2=int($mh1+1); $yh2=$yh1; if ($mh2>12) {$mh2=1;$yh2++;} ($yg1, $mg1, $dg1, $dw2) = $self->BH2GA(int($yh2), int($mh2)); $yg1=int($yg1); $mg1= int($mg1); $dg1 = int($dg1); $dw2 = int($dw2); if ($dg==$dg1) {$yh1=$yh2;$mh1=$mh2;$dh1=1;} # Make sure that the month is 30days if not make adjustment } $J= int ($self->GCalendarToJD($yg,$mg,$dg)+2); $dayweek= $J % 7; #print "there $dayweek= $J % 7\n"; $yh=$yh1; $mh=$mh1; $dh=$dh1; return ($flag, $yh, $mh, $dh, $dayweek); } #========================================================== =H2GA Name: H2GA Type: Procedure Purpose: convert Hdate(year,month,day) to Gdate(year,month,day) Arguments: Input/Ouput: Hijrah date: year:yh, month:mh, day:dh Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek and returns flag found:1 not found:0 Note: The function will correct Hdate if day=30 and the month is 29 only int H2GA(int *yh,int *mh,int *dh, int *yg,int *mg, int *dg,int *dayweek) =cut sub H2GA{ my ($self, $yh, $mh, $dh, $yg, $mg, $dg, $dayweek) = @_; my ($found,$yh1,$mh1,$yg1,$mg1,$dg1,$dw1); #make sure values are within the allowed values if ($dh>30) {$dh=1;$mh++;} if ($dh<1) {$dh=1; $mh--;} if ($mh>12) {$mh=1; $yh++;} if ($mh<1) {$mh=12;$yh--;} #find the date of the begining of the month ($found, $yg, $mg, $dg, $dayweek) = $self->BH2GA($yh, $mh); $dg=$dg+$dh-1; ($yg, $mg, $dg) = $self->GDateAjust($yg, $mg, $dg); # Make sure that dates are within the correct values $dayweek=$dayweek+$dh-1; $dayweek=$dayweek % 7; #find the date of the begining of the next month if ($dh==30) { $mh1=$mh+1; $yh1=$yh; if ($mh1>12) {$mh1=$mh1-12;$yh1++;} ($found, $yg1, $mg1, $dg1, $dw1) = $self->BH2GA($yh1, $mh1); if ($dg==$dg1) {$yh=$yh1;$mh=$mh1;$dh=1;} # Make sure that the month is 30days if not make adjustment } return ($found, $yg, $mg, $dg, $dayweek); } #========================================================== =JDToGCalendar Name: JDToGCalendar Type: Procedure Purpose: convert Julian Day to Gdate(year,month,day) Arguments: Input: The Julian Day: JD Output: Gregorian date: year:yy, month:mm, day:dd double JDToGCalendar(double JD, int *yy,int *mm, int *dd) =cut # (undef, $yg, $mg, $dg) = &JDToGCalendar($GJD); sub JDToGCalendar{ my ($self, $JD) = @_; my ($yy, $mm, $dd); my ($A, $B, $F); my ($alpha, $C, $E); my ($D, $Z); $Z = floor ($JD + 0.5); $F = ($JD + 0.5) - $Z; $alpha = int (($Z - 1867216.25) / 36524.25); $A = $Z + 1 + $alpha - $alpha / 4; $B = $A + 1524; $C = int (($B - 122.1) / 365.25); $D = (365.25 * $C); $E = int (($B - $D) / 30.6001); $dd = $B - $D - floor (30.6001 * $E) + $F; if ($E < 14){ $mm = $E - 1; } else{ $mm = $E - 13; } if ($mm > 2){ $yy = $C - 4716; } else{ $yy = $C - 4715; } $F=$F*24.0; return ($F, $yy, $mm, $dd); } #========================================================== =GCalendarToJD Name: GCalendarToJD Type: Function Purpose: convert Gdate(year,month,day) to Julian Day Arguments: Input : Gregorian date: year:yy, month:mm, day:dd Output: The Julian Day: JD double GCalendarToJD(int yy,int mm, double dd) =cut sub GCalendarToJD{ my ($self, $yy, $mm, $dd) = @_; my ($A, $B, $m, $y); my ($T1, $T2, $Tr); # it does not take care of 1582correction assumes correct calender from the past if ($mm > 2) { $y = int($yy); $m = int ($mm); } else { $y = int ($yy - 1); $m = $mm + 12; } $A = int($y / 100); $B = int(2 - $A + $A / 4); $T1 = $self->ip (365.25 * ($y + 4716)); $T2 = $self->ip (30.6001 * ($m + 1)); $Tr = $T1+ $T2 + $dd + $B - 1524.5 ; return (int $Tr); } #========================================================== =GLeapYear Name: GLeapYear Type: Function Purpose: Determines if Gdate(year) is leap or not Arguments: Input : Gregorian date: year Output: 0:year not leap 1:year is leap int GLeapYear(int year) =cut sub GLeapYear{ my ($self, $year) = @_; my ($T); $T=0; if ($year % 4 ==0) {$T=1;} # leap_year=1; if ($year % 100 == 0) { $T=0; # years=100,200,300,500,... are not leap years if ($year % 400 ==0) {$T=1;} # years=400,800,1200,1600,2000,2400 are leap years } return ($T); } #========================================================== =GDateAjust Name: GDateAjust Type: Procedure Purpose: Adjust the G Dates by making sure that the month lengths are correct if not so take the extra days to next month or year Arguments: Input: Gregorian date: year:yg, month:mg, day:dg Output: corrected Gregorian date: year:yg, month:mg, day:dg void GDateAjust(int *yg,int *mg,int *dg) =cut sub GDateAjust{ my ($self, $yg, $mg, $dg) = @_; my ($dys); # Make sure that dates are within the correct values # Underflow if ( $mg<1) #months underflow { $mg=12+$mg; # plus as the underflow months is negative $yg=$yg-1; } if ($dg<1) # days underflow { $mg= $mg-1; # month becomes the previous month $dg=$gmonth[$mg]+$dg; # number of days of the month less the underflow days (it is plus as the sign of the day is negative) if ($mg==2) {$dg=$dg+ $self->GLeapYear($yg)}; if ($mg<1) # months underflow { $mg=12+$mg; #plus as the underflow months is negative $yg=$yg-1; } } #Overflow if ($mg>12) # months { $mg=$mg-12; $yg=$yg+1; } if($mg==2){ $dys=int ($gmonth[$mg]+ $self->GLeapYear($yg) ); # number of days in the current month } else{ $dys=int($gmonth[$mg]); } if ($dg>$dys) # days overflow { $dg=$dg-$dys; $mg=$mg+1; if ($mg==2) { $dys= int($gmonth[$mg]+ $self->GLeapYear($yg));# number of days in the current month if ($dg>$dys) { $dg=$dg-$dys; $mg=$mg+1; } } if ($mg>12) # months { $mg=$mg-12; $yg=$yg+1; } } return ($yg, $mg, $dg); } #========================================================== =DayWeek The day of the week is obtained as Dy=(Julian+1)%7 Dy=0 Sunday Dy=1 Monday ... Dy=6 Saturday int DayWeek(long JulianD) =cut sub DayWeek{ my ($self, $JulianD) = @_; my ($Dy); $Dy= int (($JulianD+1) % 7); return ($Dy); } #========================================================== =HCalendarToJD Name: HCalendarToJD Type: Function Purpose: convert Hdate(year,month,day) to estimated Julian Day Arguments: Input : Hijrah date: year:yh, month:mh, day:dh Output: The Estimated Julian Day: JD double HCalendarToJD(int yh,int mh,int dh) =cut sub HCalendarToJD{ my ($self, $yh, $mh, $dh) = @_; my ($md, $yd); #Estimating The JD for hijrah dates #this is an approximate JD for the given hijrah date $md=($mh-1.0)*29.530589; $yd=($yh-1.0)*354.367068+$md+$dh-1.0; $yd=$yd+1948439.0; # add JD for 18/7/622 first Hijrah date return $yd; } #========================================================== =JDToHCalendar Name: JDToHCalendar Type: Procedure Purpose: convert Julian Day to estimated Hdate(year,month,day) Arguments: Input: The Julian Day: JD Output : Hijrah date: year:yh, month:mh, day:dh void JDToHCalendar(double JD,int *yh,int *mh,int *dh) =cut #Estimating the hijrah date from JD sub JDToHCalendar{ my ($self, $JD) = @_; my ($yh, $mh, $dh); my ($md, $yd); $yd=$JD-1948439.0; # subtract JD for 18/7/622 first Hijrah date $md= $self->mod ($yd, 354.367068); $dh= int($self->mod($md+0.5, 29.530589)+1); $mh=int(($md/29.530589)+1); $yd=$yd-$md; $yh=int($yd/354.367068+1); if ($dh>30) {$dh=int($dh-30); $mh++;} if ($mh>12) {$mh=int($mh-12); $yh++;} return ($yh, $mh, $dh); } #========================================================== =JDToHACalendar Name: JDToHACalendar Type: Procedure Purpose: convert Julian Day to Hdate(year,month,day) Arguments: Input: The Julian Day: JD Output : Hijrah date: year:yh, month:mh, day:dh void JDToHACalendar(double JD,int *yh,int *mh,int *dh) =cut sub JDToHACalendar{ my ($self, $JD) = @_; my ($yh, $mh, $dh); my ($yh1, $mh1,$dh1); my ($yh2,$mh2,$dh2); my ($yg1,$mg1,$dg1); my ($yg2,$mg2,$dg2); my ($df,$dw2); my ($flag); my ($J); my ($GJD, $HJD); ($yh1,$mh1,$dh1) = $self->JDToHCalendar($JD); # estimate the Hdate that correspond to the Gdate $HJD = $self->HCalendarToJDA(int($yh1), int($mh1), int($dh1)); #// get the exact Julian Day $df= int($JD+0.5-$HJD); $dh1= int($dh1+$df); while ($dh1>30) { $dh1= int($dh1-$self->HMonthLength($yh1,$mh1)); $mh1++; if ($mh1>12) {$yh1++;$mh1=1;} } if ($dh1==30 && $self->HMonthLength($yh1,$mh1)<30) { $dh1=1;$mh1++; } if ($mh1>12) { $mh1=1;$yh1++; } #// J=JD+2; *dayweek=J%7; $yh=$yh1; $mh=$mh1; $dh=$dh1; return ($yh, $mh, $dh); } #========================================================== # Purpose: return the integral part of a double value. sub ip{ my ($self, $x) = @_; my ($fractional, $integral); ($fractional, $integral) = POSIX::modf($x); return $integral; } #========================================================== # Name: mod # Purpose: The mod operation for doubles x mod y sub mod{ my ($self, $x, $y) = @_; my ($r, $d); $d=$x/$y; $r=int ($d); if ($r<0) {$r--;} $d=$x-$y*$r; $r= int($d); return $r; } #========================================================== #Purpose: returns 0 for incorrect Hijri date and 1 for correct date sub IsValid{ my ($self, $yh, $mh, $dh) = @_; my ($valid); $valid=1; if ($yh<$HStartYear || $yh>$HEndYear) {$valid=0;} if ($mh<1 || $mh>12 || $dh<1){ $valid=0; } else{ if ($dh>$self->HMonthLength($yh,$mh)) {$valid=0;} } return $valid; } #========================================================== sub TimeZoneUS{ my ($self, $state) = @_; if (exists $TimeZoneUS{$state}) { return $TimeZoneUS{$state}; } return undef; } #========================================================== sub TimeZoneCountry{ my ($self, $country) = @_; if (exists $TimeZone{$country}) { return $TimeZone{$country}; } return undef; } #========================================================== 1; __END__ =head1 NAME Religion::Islam::PrayerTimes - Calculates Muslim Prayers Times and Sunrise =head1 SYNOPSIS use Religion::Islam::PrayerTimes; #create new object with default options my $prayer = Religion::Islam::PrayerTimes->new(); #Juristic Methods: # 1 = Standard (Imams Shafii, Hanbali, and Maliki), #2 = Hanafi #The difference is in the Aser time only $prayer->JuristicMethod(1); # Calculation Method #1: Umm Al-Qura Committee #2: Muslim World League #3: Egyptian General Authority of Survey #4: University Of Islamic Sciences, Karachi #5: ISNA, Islamic Society of North America $prayer->CalculationMethod(3); # Q. What is daylight saving? Ans. Many countries try to adopt their work time by subtracting # from their clocks one hour in the Fall and Winter seasons. $prayer->DaylightSaving(1); #print "DaylightSaving: ". $prayer->DaylightSaving() ."\n"; # set the location to clculate prayer times for. # for Cairo, Egypt: # http://heavens-above.com/countries.asp $prayer->PrayerLocation( Latitude => 30.050, Longitude => 31.250, Altitude => 24, TimeZone => 2 ); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mon++; $year += 1900; #Adjust the Gregorian Dates by making sure that the month lengths #are correct if not so take the extra days to next month or year. my ($yg0, $mg0, $dg0) = $prayer->GDateAjust($year, $mon, $mday); # Now calculate the prayer times. Times returns in hours decimal format #%result = $prayer->PrayerTimes($year, $mon, $mday); %result = $prayer->PrayerTimes($yg0, $mg0, $dg0); #print "Fajr: " . $result{Fajr} . "\n"; #print "Sunrise: " . $result{Sunrise} . "\n"; #print "Zohar: " . $result{Zohar} . "\n"; #print "Aser: " . $result{Aser} . "\n"; #print "Maghrib: " . $result{Maghrib} . "\n"; #print "Isha: " . $result{Isha} . "\n"; #print "Fajir Rabita: " . $result{FajirRabita} . "\n"; #Fajer using exact Rabita method for places >48 #print "Isha Rabita: " . $result{IshaRabita} . "\n"; #Ash using exact Rabita method for places >48 #print "Eid Prayer Time: " . $result{Eid} . "\n"; #Eid Prayer Time #print "\n"; # set time mode for 12 or 24 hour for FormatTime function. $prayer->TimeMode(1); #print time formated #print "TimeMode: " . $prayer->TimeMode() ."\n"; my ($h, $m, $ap); ($h, $m, $ap) = $prayer->FormatTime($result{Fajr}); print "Fajr: $h:$m $ap\n"; ($h, $m, $ap) = $prayer->FormatTime($result{Sunrise}); print "Sunrise: $h:$m $ap\n"; ($h, $m, $ap) = $prayer->FormatTime($result{Zohar}); print "Zohar: $h:$m $ap\n"; ($h, $m, $ap) = $prayer->FormatTime($result{Aser}); print "Aser: $h:$m $ap\n"; ($h, $m, $ap) = $prayer->FormatTime($result{Maghrib}); print "Maghrib: $h:$m $ap\n"; ($h, $m, $ap) = $prayer->FormatTime($result{Isha}); print "Isha: $h:$m $ap\n"; #($h, $m, $ap) = $prayer->FormatTime($result{FajirRabita}); #print "Fajir Rabita: $h:$m $ap\n"; #Fajer using exact Rabita method for places >48 #($h, $m, $ap) = $prayer->FormatTime($result{IshaRabita}); #print "Isha Rabita: $h:$m $ap\n"; #Ash using exact Rabita method for places >48 #($h, $m, $ap) = $prayer->FormatTime($result{Eid}); #print "Eid Prayer Time: $h:$m $ap\n"; #Eid Prayer Time =head1 DESCRIPTION This module calculates Muslim prayers times and sunrise for any location on the earth. =head1 SEE ALSO L L =head1 AUTHOR Ahmed Amin Elsheshtawy, Esupport@islamware.com Website: http://www.islamware.com =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by Ahmed Amin Elsheshtawy support@islamware.com, L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Religion-Islam-PrayerTimes-1.02/t/0040755000000000000000000000000010464212137015456 5ustar rootrootReligion-Islam-PrayerTimes-1.02/t/Religion-Islam-PrayerTimes.t0100644002343400234210000000100710463705372024254 0ustar islamwarepsacln# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl Religion-Islam-PrayerTimes.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More tests => 1; BEGIN { use_ok('Religion::Islam::PrayerTimes') }; ######################### # Insert your test code below, the Test::More module is use()ed here so read # its man page ( perldoc Test::More ) for help writing this test script. Religion-Islam-PrayerTimes-1.02/README0100644002343400234210000000075210463705371017434 0ustar islamwarepsaclnReligion-Islam-PrayerTimes version 1.0 ======================================= INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES None COPYRIGHT AND LICENCE Copyright (C) 2006 by Dr. Ahmed Amin Elsheshtawy support@mewsoft.com http://www.mewsoft.com, http://www.islamware.com This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Religion-Islam-PrayerTimes-1.02/Makefile.PL0100644002343400234210000000112110463705367020522 0ustar islamwarepsaclnuse ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'Religion::Islam::PrayerTimes', VERSION_FROM => 'lib/Religion/Islam/PrayerTimes.pm', # finds $VERSION PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Religion/Islam/PrayerTimes.pm', # retrieve abstract from module AUTHOR => 'Ahmed Amin ELsheshtawy ') : ()), );