Add support for conversion to/from the Jalali calendar

master
Ehsan Akhgari 2014-08-09 21:56:47 -04:00 committed by Matt Miller
parent e5e13c30fc
commit 6f1b8179ae
3 changed files with 83 additions and 30 deletions

View File

@ -23,6 +23,7 @@ Text::FIGlet = 2.19.3
Text::Unidecode = 0.04
Date::Calc = 6.3
Date::Hijri = 0.02
Date::Jalali2 = 0.04
Date::Leapyear = 1.72
; Dates role, et. al.
DateTime = 0.74

View File

@ -4,63 +4,87 @@ package DDG::Goodie::CalendarConversion;
use DDG::Goodie;
use Date::Hijri;
use Date::Jalali2;
zci answer_type => "calendar_conversion";
zci answer_type => "conversion";
primary_example_queries '22/8/2003 to the hijri calendar';
secondary_example_queries '23/6/1424 to gregorian';
description 'convert dates from the Gregorian calendar to the Hijri calendar and back';
secondary_example_queries '23/6/1424 hijri to gregorian';
description 'convert dates from the Gregorian calendar to the Hijri/Jalali calendars and back';
name 'CalendarConversion';
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/CalendarConversion.pm';
category 'dates';
topics 'special_interest';
attribution github => [ 'http://github.com/mattlehning', 'mattlehning' ];
attribution github => ['http://github.com/mattlehning', 'mattlehning'],
github => ['http://github.com/ehsan', 'ehsan'];
triggers any => 'hijri', 'gregorian';
triggers any => 'hijri', 'gregorian', 'jalali';
my %calendars = (
'gregorian' => ['Gregorian calendar', '<a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a>'],
'hijri' => ['Hijri calendar','<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a>'],
'hijri' => ['Hijri calendar', '<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a>'],
'jalali' => ['Jalali calendar', '<a href="https://en.wikipedia.org/wiki/Jalali_calendar">Jalali calendar</a>'],
);
# This function returns either the HTML version of the output or the text version.
sub output {
my ($calendar_first, $calendar_second, $input_date, $converted_date, $is_html) = @_;
return "$input_date on the " . $calendars{$calendar_first}[$is_html] . " is $converted_date on the " . $calendars{$calendar_second}[$is_html] . '.';
return
"$input_date on the "
. $calendars{$calendar_first}[$is_html]
. " is $converted_date on the "
. $calendars{$calendar_second}[$is_html] . '.';
}
handle query_lc => sub {
return unless my ($gd, $gm, $gy, $input_calendar, $output_calendar) = $_ =~
/^
return unless my ($d, $m, $y, $input_calendar, $output_calendar) = $_ =~ /^
(\d{0,2})(?:\/|,)(\d{0,2})(?:\/|,)(\d{3,4})\s+
(?:
(?:on\s+the)\s+
((?:gregorian|hijri)?)\s+
(?:calendar|date|time)\s+
is\s+
(?:(?:in|on(?:\s+the))?)\s*
((?:gregorian|hijri|jalali)?)\s+
(?:calendar|date|time)?\s*
(?:is\s+)?
)?
(?:
(?:(?:in|on|to)(?:\s+the|in)?)\s+
)?
(gregorian|hijri)\s*
(gregorian|hijri|jalali)\s*
(?:calendar|date|time|years|months|days)?
$/x;
return unless ($gd < 31 and $gm < 12);
my $is_hijri = $output_calendar eq 'hijri';
return unless ($d < 32 and $m < 12);
my ($hd, $hm, $hy) = $is_hijri ? g2h($gd, $gm, $gy) : h2g($gd, $gm, $gy);
my $input_date = "$gd/$gm/$gy";
my $converted_date = "$hd/$hm/$hy";
$input_calendar //= 'gregorian'; # gregorian is the default
return if ($input_calendar eq $output_calendar);
# Check if the user wants to convert to either Hijri or Gregorian.
if($is_hijri) {
return output('gregorian', 'hijri', $input_date, $converted_date, 0),
html => output('gregorian', 'hijri', $input_date, $converted_date, 1);
}
return output('hijri', 'gregorian', $input_date, $converted_date, 0),
html => output('hijri', 'gregorian', $input_date, $converted_date, 1);
my $input_date = "$d/$m/$y";
my $converted_date;
if ($input_calendar eq "hijri" and $output_calendar eq "gregorian") {
my ($gd, $gm, $gy) = h2g($d, $m, $y);
$converted_date = "$gd/$gm/$gy";
} elsif ($input_calendar eq "gregorian" and $output_calendar eq "hijri") {
my ($hd, $hm, $hy) = g2h($d, $m, $y);
$converted_date = "$hd/$hm/$hy";
} elsif ($input_calendar eq "jalali" and $output_calendar eq "gregorian") {
my $t = new Date::Jalali2($y, $m, $d, 1);
$converted_date = $t->jal_day . "/" . $t->jal_month . "/" . $t->jal_year;
} elsif ($input_calendar eq "gregorian" and $output_calendar eq "jalali") {
my $t = new Date::Jalali2($y, $m, $d, 0);
$converted_date = $t->jal_day . "/" . $t->jal_month . "/" . $t->jal_year;
} elsif ($input_calendar eq "hijri" and $output_calendar eq "jalali") {
my ($gd, $gm, $gy) = h2g($d, $m, $y);
my $t = new Date::Jalali2($gy, $gm, $gd, 0);
$converted_date = $t->jal_day . "/" . $t->jal_month . "/" . $t->jal_year;
} elsif ($input_calendar eq "jalali" and $output_calendar eq "hijri") {
my $t = new Date::Jalali2($y, $m, $d, 1);
my ($hd, $hm, $hy) = g2h($t->jal_day, $t->jal_month, $t->jal_year);
$converted_date = "$hd/$hm/$hy";
}
return output($input_calendar, $output_calendar, $input_date, $converted_date, 0),
html => output($input_calendar, $output_calendar, $input_date, $converted_date, 1);
};
1;

View File

@ -5,7 +5,7 @@ use warnings;
use Test::More;
use DDG::Test::Goodie;
zci answer_type => 'conversion';
zci answer_type => 'calendar_conversion';
zci is_cached => 0;
ddg_goodie_test(
@ -31,17 +31,45 @@ ddg_goodie_test(
. 'is 23/6/1424 on the '
. '<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a>.'
),
'23/6/1424 to gregorian years' => test_zci(
'23/6/1424 in hijri to gregorian years' => test_zci(
'23/6/1424 on the Hijri calendar is 22/8/2003 on the Gregorian calendar.',
html => '23/6/1424 on the '
. '<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a> '
. 'is 22/8/2003 on the '
. '<a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a>.'
),
'23/6/1424 to gregorian' => test_zci(
'23/6/1424 hijri to gregorian' => test_zci(
'23/6/1424 on the Hijri calendar is 22/8/2003 on the Gregorian calendar.',
html => '23/6/1424 on the <a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a> is 22/8/2003 on the <a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a>.'
),
'22/8/2003 to jalali' => test_zci(
'22/8/2003 on the Gregorian calendar is 31/5/1382 on the Jalali calendar.',
html => '22/8/2003 on the '
. '<a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a> '
. 'is 31/5/1382 on the '
. '<a href="https://en.wikipedia.org/wiki/Jalali_calendar">Jalali calendar</a>.'
),
'31/5/1382 jalali to gregorian' => test_zci(
'31/5/1382 on the Jalali calendar is 22/8/2003 on the Gregorian calendar.',
html => '31/5/1382 on the '
. '<a href="https://en.wikipedia.org/wiki/Jalali_calendar">Jalali calendar</a> '
. 'is 22/8/2003 on the '
. '<a href="https://en.wikipedia.org/wiki/Gregorian_calendar">Gregorian calendar</a>.'
),
'31/5/1382 jalali to hijri' => test_zci(
'31/5/1382 on the Jalali calendar is 23/6/1424 on the Hijri calendar.',
html => '31/5/1382 on the '
. '<a href="https://en.wikipedia.org/wiki/Jalali_calendar">Jalali calendar</a> '
. 'is 23/6/1424 on the '
. '<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a>.'
),
'23/6/1424 in hijri to jalali date' => test_zci(
'23/6/1424 on the Hijri calendar is 31/5/1382 on the Jalali calendar.',
html => '23/6/1424 on the '
. '<a href="https://en.wikipedia.org/wiki/Hijri_calendar">Hijri calendar</a> '
. 'is 31/5/1382 on the '
. '<a href="https://en.wikipedia.org/wiki/Jalali_calendar">Jalali calendar</a>.'
),
);
done_testing;