Date-HijriDate
view release on metacpan or search on metacpan
lib/Date/HijriDate.pm view on Meta::CPAN
#=Copyright Infomation
#==========================================================
#Module Name : Date::HijriDate
#Program Author : Dr. Ahmed Amin Elsheshtawy, Ph.D. Physics, E.E.
#Home Page : http://www.islamware.com, http://www.mewsoft.com
#Contact Email : support@islamware.com, support@mewsoft.com
#Copyrights © 2013 IslamWare. All rights reserved.
#==========================================================
package Date::HijriDate;
use strict;
use POSIX;
require Exporter;
our @ISA = 'Exporter';
our @EXPORT = qw(hijri_date hijri_now hijri_time);
our $VERSION = '1.01';
our %weekday = (
'en' => ["Ahad","Ithnin","Thulatha","Arbaa","Khams","Jumuah","Sabt"],
'ar' => ["Ø§ÙØ£ØØ¯","Ø§ÙØ£Ø«ÙÙÙ","Ø§ÙØ«Ùاثاء","Ø§ÙØ£Ø±Ø¨Ø¹Ø§Ø¡","Ø§ÙØ®Ù
ÙØ³","Ø§ÙØ¬Ù
عة","Ø§ÙØ³Ø¨Øª"]
);
our %month = (
'en' => ["Muharram","Safar","Rabi'ul Awwal","Rabi'ul Akhir", "Jumadal Ula","Jumadal Akhira",
"Rajab","Sha'ban", "Ramadan","Shawwal","Dhul Qa'ada","Dhul Hijja"],
'ar' => ["Ù
ØØ±Ù
","ØµÙØ±","Ø±Ø¨ÙØ¹ Ø§ÙØ£ÙÙ","Ø±Ø¨ÙØ¹ Ø§ÙØ«Ø§ÙÙ", "جÙ
Ø§Ø¯Ù Ø§ÙØ£ÙÙ","جÙ
Ø§Ø¯Ù Ø§ÙØ«Ø§ÙÙ",
"رجب","شعباÙ", "رÙ
ضاÙ","Ø´ÙØ§Ù","ذ٠اÙÙØ¹Ø¯Ø©","Ø°Ù Ø§ÙØØ¬Ø©"]
);
#=========================================================#
#Arithmetical calendar type
#Ic [â15â, civil]
#Ia [â15â, astronomical]
#IIc [â16â, civil]
#IIa [â16â, astronomical = âMS HijriCalendarâ]
#IIIc [FÄtimid, civil]
#IIIa [FÄtimid, astronomical]
#IVc [Habash al-HÄsib, civil]
#IVa [Habash al-HÄsib, astronomical]
# generalized modulo function (n mod m) also valid for negative values of n
sub gmod {
my ($n, $m) = @_;
return (($n % $m) + $m) % $m;
}
sub hijri_time {
my ($time, $caltype, $lang) = @_;
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime($time);
return hijri_date($mday, $mon, $year+1900, $caltype, $lang);
}
sub hijri_now {
my ($caltype, $lang) = @_;
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime(time);
return hijri_date($mday, $mon, $year+1900, $caltype, $lang);
}
sub hijri_date {
my ($day, $month, $year, $caltype, $lang) = @_;
my (%ret);
# $month: 0-11
# $year: yyyy
# $caltype: 0= Julian, 1=Gregorian
$caltype += 0;
if (!exists $weekday{$lang}) {
$lang = 'en';
}
my $m = $month + 1;
my $y = $year;
# append January and February to the previous year (i.e. regard March as
# the first month of the year in order to simplify leapday corrections)
if ($m < 3) {
$y -= 1;
$m += 12;
}
# determine offset between Julian and Gregorian calendar
my $jgc;
if ($y < 1583) {$jgc = 0};
if ($y == 1582) {
if ($m > 10) {$jgc = 10;}
if ($m == 10 && $day < 5 ) {$jgc = 0;}
if ($m == 10 && $day > 14) {$jgc = 10;}
if ($m == 10 && $day > 4 && $day < 15) {
if ($caltype == 0) {
$jgc = 10;
$day += 10;
}
if ($caltype == 1) {
$jgc = 0;
$day -= 10;
}
}
}
if ($y > 1582) {
$a = floor($y/100);
$jgc = $a - floor($a/4) - 2;
}
# compute Chronological Julian Day Number (CJDN)
my $cjdn = floor(365.25*($y + 4716)) + floor(30.6001*($m+1)) + $day - $jgc - 1524;
# output calendar type (0 = Julian; 1 = Gregorian)
if ($cjdn < 2299161) {
$jgc = 0;
$ret{caltype} = 0;
}
if ($cjdn > 2299160) {
$ret{caltype} = 1;
$a = floor(($cjdn - 1867216.25)/36524.25);
$jgc = $a - floor($a/4) + 1;
}
$b = $cjdn + $jgc + 1524;
my $c = floor(($b - 122.1)/365.25);
my $d = floor(365.25*$c);
$month = floor(($b - $d)/30.6001);
$day = ($b - $d) - floor(30.6001*$month);
if ($month > 13) {
$c += 1;
$month -= 12;
}
$month -= 1;
$year = $c - 4716;
# output Western calendar date
$ret{day} = $day;
$ret{month} = $month - 1;
$ret{year} = $year;
# compute weekday
my $wd = gmod($cjdn+1, 7) + 1;
#output Julian Day Number and weekday
$ret{julday} = $cjdn;
$ret{wkday} = $wd - 1;
$ret{itoday} = $weekday{$lang}->[$wd - 1];
# set mean length and epochs (astronomical & civilian) of the tabular Islamic year
my $iyear = 10631/30;
my $epochastro = 1948084;
my $epochcivil = 1948085;
# compute and output Islamic calendar date (type I)
my $shift1 = 8.01/60; # rets in years 2, 5, 7, 10, 13, 15, 18, 21, 24, 26 & 29 as leap years
my $z = $cjdn - $epochcivil;
my $cyc = floor($z/10631);
$z = $z - 10631*$cyc;
my $j = floor(($z - $shift1)/$iyear);
my $iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift1);
my $im = floor(($z + 28.5001)/29.5);
if ($im == 13) {$im = 12;}
my $id = $z - floor(29.5001*$im - 29);
$ret{iday1} = $id;
$ret{imonth1} = $im - 1;
$ret{iyear1} = $iy;
$ret{iname1} = $month{$lang}->[$im - 1];
$z = $cjdn - $epochastro;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift1)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift1);
$im = floor(($z + 28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday2} = $id;
$ret{imonth2} = $im - 1;
$ret{iyear2} = $iy;
$ret{iname2} = $month{$lang}->[$im - 1];
#compute and output Islamic calendar date (type II)
my $shift2 = 6.01/60; # rets in years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 as leap years
$z = $cjdn - $epochcivil;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift2)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift2);
$im = floor(($z+28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday3} = $id;
$ret{imonth3} = $im - 1;
$ret{iyear3} = $iy;
$ret{iname3} = $month{$lang}->[$im - 1];
$z = $cjdn - $epochastro;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift2)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift2);
$im = floor(($z + 28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday4} = $id;
$ret{imonth4} = $im - 1;
$ret{iyear4} = $iy;
$ret{iname4} = $month{$lang}->[$im - 1];
# compute and output Islamic calendar date (type III)
my $shift3 = 0.01/60; # rets in years 2, 5, 8, 10, 13, 16, 19, 21, 24, 27 & 29 as leap years
$z = $cjdn - $epochcivil;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift3)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift3);
$im = floor(($z + 28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im-29);
$ret{iday5} = $id;
$ret{imonth5} = $im - 1;
$ret{iyear5} = $iy;
$ret{iname5} = $month{$lang}->[$im - 1];
$z = $cjdn - $epochastro;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift3)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift3);
$im = floor(($z + 28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday6} = $id;
$ret{imonth6} = $im - 1;
$ret{iyear6} = $iy;
$ret{iname6} = $month{$lang}->[$im - 1];
# compute and output Islamic calendar date (type IV)
my $shift4 = -2.01/60; # rets in years 2, 5, 8, 11, 13, 16, 19, 21, 24, 27 & 30 as leap years
$z = $cjdn - $epochcivil;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift4)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift4);
$im = floor(($z+28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday7} = $id;
$ret{imonth7} = $im - 1;
$ret{iyear7} = $iy;
$ret{iname7} = $month{$lang}->[$im - 1];
$z = $cjdn - $epochastro;
$cyc = floor($z/10631);
$z = $z - 10631*$cyc;
$j = floor(($z - $shift4)/$iyear);
$iy = 30*$cyc + $j;
$z = $z - floor($j*$iyear + $shift4);
$im = floor(($z+28.5001)/29.5);
if ($im == 13) {$im = 12;}
$id = $z - floor(29.5001*$im - 29);
$ret{iday8} = $id;
$ret{imonth8} = $im - 1;
$ret{iyear8} = $iy;
$ret{iname8} = $month{$lang}->[$im - 1];
return %ret;
}
#=========================================================#
1;
=head1 NAME
Date::HijriDate - Hijri Islamic Dates Calendar
=head1 SYNOPSIS
use Date::HijriDate;
my $day = 8; # day of the month
my $month = 11; # month 0..11
my $year = 2013; # yyyy format
my $caltype = 1; # (0 = Julian; 1 = Gregorian)
my $lang = "en"; # available languages: en, ar
my %ret;
# get Hijri date for specific Gregorian day
#%ret = hijri_date($day, $month, $year, $caltype, $lang);
# get current time in Hijri
#%ret = hijri_now($caltype, $lang);
# get Hijri time for the specific time stamp
%ret = hijri_time(time, $caltype, $lang);
# Western date
$ret{month}++; # returned month 0..11
print "Western date: $ret{day}-$ret{month}-$ret{year}\n";
#Arithmetical calendar type day month year (AH)
print "'Arithmetical calendar type' day month 'year (AH)' 'month name'\n";
# all returned month 0..11
#Method 1 civil, astronomical
$ret{imonth1}++; $ret{imonth2}++;
print "Ic [15, civil] $ret{iday1}-$ret{imonth1}-$ret{iyear1} $ret{iname1}\n";
print "Ia [15, astronomical] $ret{iday2}-$ret{imonth2}-$ret{iyear2} $ret{iname2}\n";
#Method 2 civil, astronomical
$ret{imonth3}++; $ret{imonth4}++;
print "IIc [16, civil] $ret{iday3}-$ret{imonth3}-$ret{iyear3} $ret{iname3}\n";
print "IIa [16, astronomical='MS HijriCalendar'] $ret{iday4}-$ret{imonth4}-$ret{iyear4} $ret{iname4}\n";
#Method 3 civil, astronomical
$ret{imonth5}++; $ret{imonth6}++;
print "IIIc [FÄtimid, civil] $ret{iday5}-$ret{imonth5}-$ret{iyear5} $ret{iname5}\n";
print "IIIa [FÄtimid, astronomical] $ret{iday6}-$ret{imonth6}-$ret{iyear6} $ret{iname6}\n";
#Method 4 civil, astronomical
$ret{imonth7}++; $ret{imonth8}++;
print "IVc [Habash al-HÄsib, civil] $ret{iday7}-$ret{imonth7}-$ret{iyear7} $ret{iname7}\n";
print "IVa [Habash al-HÄsib, astronomical] $ret{iday8}-$ret{imonth8}-$ret{iyear8} $ret{iname8}\n";
print "Julian day: $ret{julday}\n";
print "Weekday number 0..7, 0=Sunday: $ret{wkday}\n";
print "Hijri day name: $ret{itoday}\n";
print "Calender type: ". (($ret{caltype} == 1)? "Gregorian" : "Julian") . "\n";
print "\n\n";
# print all dates information for all 8 calculation methods
foreach my $k(sort keys %ret) {
print "$k = $ret{$k}\n";
}
# output
Western date: 9-12-2013
'Arithmetical calendar type' day-month-'year (AH)' 'month name'
Ic [15, civil] 5-2-1435 Safar
Ia [15, astronomical] 6-2-1435 Safar
IIc [16, civil] 5-2-1435 Safar
IIa [16, astronomical='MS HijriCalendar'] 6-2-1435 Safar
IIIc [FÄtimid, civil] 5-2-1435 Safar
IIIa [FÄtimid, astronomical] 6-2-1435 Safar
IVc [Habash al-HÄsib, civil] 5-2-1435 Safar
IVa [Habash al-HÄsib, astronomical] 6-2-1435 Safar
Julian day: 2456636
Weekday number 0..7, 0=Sunday: 1
Hijri day name: Ithnin
Calender type: Gregorian
=head1 DESCRIPTION
This module calculates Islamic Hijri calender dates using civil and astronomical 8 methods.
Arithmetical calendar type:
Ic [15, civil]
Ia [15, astronomical]
IIc [16, civil]
IIa [16, astronomical = "MS HijriCalendar"]
IIIc [FÄtimid, civil]
IIIa [FÄtimid, astronomical]
IVc [Habash al-HÄsib, civil]
IVa [Habash al-HÄsib, astronomical]
Exports three methods hijri_time, hijri_now, and hijri_date.
All methods return date information in a single hash.
%ret = hijri_time($time, $caltype, $lang);
$time: unix time stamp;
$caltype: 0 = Julian, 1 = Gregorian
$lang: en, ar only currently supported for weekday and month names.
%ret = hijri_now($caltype, $lang)
return current Hijri time
%ret = hijri_date($day, $month, $year, $caltype, $lang)
return Hijri date for a given western date.
$month: 0..11
$year: yyyy format
=head1 SEE ALSO
L<Religion::Islam::Qibla>
L<Religion::Islam::Quran>
L<Religion::Islam::PrayTime>
L<Religion::Islam::PrayerTimes>
=head1 AUTHOR
Ahmed Amin Elsheshtawy, <support@islamware.com> <support@mewsoft.com>
Website: http://www.islamware.com http://www.mewsoft.com
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by Dr. Ahmed Amin Elsheshtawy webmaster@islamware.com,
L<http://www.islamware.com>
L<http://www.mewsoft.com>
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
( run in 3.634 seconds using v1.01-cache-2.11-cpan-64ef6c95b5d )