We don't bite newbies here... much PerlMonks

Convert Gregorian/Islamic Date

by projekt21 (Friar)
 on Aug 21, 2003 at 15:04 UTC Need Help??
 Category: Miscellaneous Author/Contact Info Alex Pleiner Description: My wife needed to know some islamic festival dates, so I wrote a conversion module (stealing code from KDE). It still misses features like getting the day of week and others. If anybody is interested I will expand it and/or implement it into Date::Convert as a subclass. Please give me some comments. ```package Date::Hijri; require 5.001; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(h2g g2h); our @EXPORT_OK = qw(); our \$VERSION = '0.01'; ############################################################ use constant IslamicEpoch => 227014; ############################################################ sub g2h { my (\$day, \$month, \$year) = @_; return Absolute2Islamic(Gregorian2Absolute(\$day, \$month, \$year)); } sub h2g { my (\$day, \$month, \$year) = @_; return Absolute2Gregorian(Islamic2Absolute(\$day, \$month, \$year)); } sub lastDayOfGregorianMonth { # Compute the last date of the month for the Gregorian calendar. my (\$month, \$year) = @_; 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 Gregorian2Absolute { # Computes the absolute date from the Gregorian date. my (\$day, \$month, \$year) = @_; my \$N = \$day; # days this month for (my \$m = \$month - 1; \$m > 0; \$m--) # days in prior months this + year { \$N += lastDayOfGregorianMonth(\$m, \$year); } return int(\$N # days this year + 365 * (\$year - 1) # days in previous years igno +ring leap days + (\$year - 1) / 4 # Julian leap days before thi +s year... - (\$year - 1) / 100 # ...minus prior century year +s... + (\$year - 1) / 400); # ...plus prior years divisib +le by 400 } sub Absolute2Gregorian { # Computes the Gregorian date from the absolute date. my (\$d) = @_; # Search forward year by year from approximate year my \$year = int(\$d / 366 + 0.5); while (\$d >= Gregorian2Absolute(1,1,\$year+1)) { \$year++; } # Search forward month by month from January my \$month = 1; while (\$d > Gregorian2Absolute(lastDayOfGregorianMonth(\$month, \$ye +ar), \$month, \$year)) { \$month++; } my \$day = \$d - Gregorian2Absolute(1, \$month, \$year) + 1; return (\$day, \$month, \$year); } sub IslamicLeapYear { # True if year is an Islamic leap year my (\$year) = @_; return ((((11 * \$year) + 14) % 30) < 11) ? 1 : 0; } sub lastDayOfIslamicMonth { # Last day in month during year on the Islamic calendar. my (\$month, \$year) = @_; return (\$month % 2 == 1) || (\$month == 12 && IslamicLeapYear(\$year +)) ? 30 : 29; } sub Islamic2Absolute { # Computes the absolute date from the Islamic date. my (\$day, \$month, \$year) = @_; return int(\$day # days so far this month + 29 * (\$month - 1) # days so far... + int(\$month /2) # ...this year + 354 * (\$year - 1) # non-leap days in prior year +s + (3 + (11 * \$year)) / 30 # leap days in prior years + IslamicEpoch); # days before start of calend +ar } sub Absolute2Islamic { # Computes the Islamic date from the absolute date. my (\$d) = @_; my (\$day, \$month, \$year); if (\$d <= IslamicEpoch) { # Date is pre-Islamic \$month = 0; \$day = 0; \$year = 0; } else { # Search forward year by year from approximate year \$year = int((\$d - IslamicEpoch) / 355); while (\$d >= Islamic2Absolute(1,1,\$year+1)) { \$year++; } # Search forward month by month from Muharram \$month = 1; while (\$d > Islamic2Absolute(lastDayOfIslamicMonth(\$month,\$yea +r), \$month, \$year)) { \$month++ } \$day = \$d - Islamic2Absolute(1, \$month, \$year) + 1; } return (\$day, \$month, \$year); } 1; __END__ ############################################################ =head1 NAME Date::Hijri - Perl extension to convert islamic (hijri) and gregorian +dates. =head1 SYNOPSIS use Date::Hijri; # convert gregorian to hijri date my (\$hd, \$hm, \$hy) = g2h(\$gd, \$gm, \$gy); # convert hijri to gregorian date my (\$gd, \$gm, \$gy) = h2g(\$hd, \$hm, \$hy); =head1 DESCRIPTION This simple module converts gregorian dates to islamic (hijri) and vic +e versa. The dates must be given as an array containing the day, month and year +, and return the corresponding date as a list with the same elements. =head1 EXAMPLES #!/usr/bin/perl -w use Date::Hijri; print join("-", g2h(22,8,2003)); # prints 23-6-1424 print join("-", h2g(23,6,1424)); # prints 22-8-2003 =head1 SEE ALSO This code is just stolen from KDE's L at http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdelibs/kdecore/kcalendarsyst +emhijri.cpp Copyright (c) 2002-2003 Carlos Moro Copyright (c) 2002-2003 Hans Petter Bieker kcalendarsystemhijri.cpp is translated from the Lisp code in ``Calendrical Calculations'' by Nachum Dershowitz and Edward M. Reingold, Software---Practice & Experience, vol. 20, no. 9 (September, 1990), pp. 899--928. This code is in the public domain, but any use of it should publically acknowledge its source. =head1 AUTHOR Alex Pleiner, Ealex@zeitform.deE =head1 COPYRIGHT AND LICENSE Copyright (c) 2001, 2003 zeitform Internet Dienste. All rights reserve +d. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 DISCLAIMER I haven't really tested if the converted dates are right and hope someone will point out mistakes. Hijri calculations are very difficult. The islamic calendar is a pure lunar calendar, the new month starts by a physical (i.e. human) sighting of the crescent moon at a given locale. So it depends on several factors (like weather) that make it unreliable to calculate islamic calendars in advance. As a result the dates calculated by Date::Hijri can be false by one or more days. Please see http://www.rabiah.com/convert/introduction.html for further explanation. I'm not a muslim, but interested in Islamic culture, religion and calendar system. I believe in the Internet as a chance to realize that we live in a small world with multiple cultures, religions and philosophies. We can learn from others and develop tolerance, respect and understanding. Salam Alaikum (peace be with you) =cut ## -fin- ```
Replies are listed 'Best First'.
Re: Convert Gregorian/Islamic Date
by bm (Hermit) on Aug 21, 2003 at 15:50 UTC
Hi, this looks interesting (++), except for require 5.001; Why is that?
--
bm

Good question, I guess it was in that template file I used ...

My current h2xs (version 1.22) would have given:

```use 5.008;
use strict;
use warnings;

Update: As I got a downvote for this statement, I started reading perldelta and yes, this is totally bullshit. If I read thoroughly enough, then our was introduced with version 5.6.0 and I had to

```use 5.6.0;
or better drop this and our in favourite of use vars to support older versions. Looks like no other part of this code requires a newer version.

alex pleiner <alex@zeitform.de>
zeitform Internet Dienste

Create A New User
Node Status?
node history
Node Type: sourcecode [id://285487]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2021-04-14 06:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?