2013-11-01 09:09:57 -07:00
|
|
|
package DDG::Goodie::LeapYear;
|
|
|
|
# ABSTRACT: Check if a year is leap year
|
2014-08-20 11:45:33 -07:00
|
|
|
|
2015-02-22 12:09:29 -08:00
|
|
|
use strict;
|
2013-11-01 09:09:57 -07:00
|
|
|
use DDG::Goodie;
|
|
|
|
use Date::Leapyear;
|
|
|
|
|
|
|
|
zci answer_type => "leap_year";
|
|
|
|
|
|
|
|
primary_example_queries 'is it a leap year';
|
2013-11-17 16:08:06 -08:00
|
|
|
secondary_example_queries 'when were the last 50 leap years';
|
2013-11-01 09:09:57 -07:00
|
|
|
description 'Check if it is a leap year';
|
|
|
|
name 'Leap year';
|
|
|
|
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/LeapYear.pm';
|
2013-11-21 16:46:56 -08:00
|
|
|
category 'dates';
|
2013-11-01 09:09:57 -07:00
|
|
|
topics 'everyday';
|
2013-11-21 16:46:56 -08:00
|
|
|
attribution github => [ 'https://github.com/tophattedcoder', 'Tom Bebbington'],
|
2015-07-14 23:55:22 -07:00
|
|
|
twitter => ['@tophattedcoder', 'Tom Bebbington'],
|
|
|
|
github => ['https://github.com/Sloff', 'Sloff'];
|
2013-11-01 09:09:57 -07:00
|
|
|
|
2014-01-25 15:15:19 -08:00
|
|
|
zci is_cached => 1;
|
2013-11-16 06:06:57 -08:00
|
|
|
triggers startend => 'leap years', 'leap year';
|
2013-11-17 16:57:50 -08:00
|
|
|
# 'is' in tenses
|
2013-11-17 06:30:00 -08:00
|
|
|
my %is_tense = (
|
|
|
|
past => 'was',
|
|
|
|
present => 'is',
|
|
|
|
future => 'will be',
|
|
|
|
);
|
2013-11-17 16:57:50 -08:00
|
|
|
# 'is not' in tenses
|
2013-11-17 06:30:00 -08:00
|
|
|
my %is_not_tense = (
|
|
|
|
past => 'was not',
|
|
|
|
present => 'is not',
|
|
|
|
future => 'will not be',
|
|
|
|
);
|
2015-01-02 03:23:54 -08:00
|
|
|
|
2013-11-17 16:57:50 -08:00
|
|
|
# searches for leap years
|
2013-11-17 15:55:57 -08:00
|
|
|
sub search_leaps {
|
2013-11-17 16:39:36 -08:00
|
|
|
my ($num, $direction, $include_curr, $curryear) = @_;
|
|
|
|
my $cyear = $curryear;
|
2013-11-17 15:55:57 -08:00
|
|
|
my @years = ();
|
2013-11-21 14:49:15 -08:00
|
|
|
if($include_curr == 0) {
|
2013-11-17 15:55:57 -08:00
|
|
|
$cyear += $direction;
|
|
|
|
}
|
2015-07-14 23:55:22 -07:00
|
|
|
while($#years + 1 < $num) {
|
2013-11-17 15:55:57 -08:00
|
|
|
while(!isleap($cyear)) {
|
|
|
|
$cyear += $direction;
|
2013-11-16 06:06:57 -08:00
|
|
|
}
|
2013-11-17 16:20:29 -08:00
|
|
|
push @years, ($cyear);
|
2015-07-17 05:49:50 -07:00
|
|
|
$direction *= 4 if abs($direction) == 1;
|
2013-11-17 15:55:57 -08:00
|
|
|
$cyear += $direction;
|
|
|
|
}
|
|
|
|
return @years;
|
|
|
|
}
|
2013-11-17 16:57:50 -08:00
|
|
|
# finds the matching tense for the given year
|
2013-11-17 15:55:57 -08:00
|
|
|
sub find_tense {
|
2015-01-02 03:23:54 -08:00
|
|
|
my ($cyear, $year) = @_;
|
2013-11-17 15:55:57 -08:00
|
|
|
if($cyear < $year) {
|
|
|
|
return "past";
|
|
|
|
} elsif($cyear > $year) {
|
|
|
|
return "future";
|
|
|
|
} else {
|
|
|
|
return "present";
|
|
|
|
}
|
|
|
|
}
|
2013-11-17 16:57:50 -08:00
|
|
|
# formats the year from an integer
|
2013-11-17 15:55:57 -08:00
|
|
|
sub format_year {
|
2013-11-17 16:39:36 -08:00
|
|
|
my ($cyear) = @_;
|
2013-11-17 15:55:57 -08:00
|
|
|
if(!defined($cyear)) {
|
|
|
|
$cyear = $_;
|
|
|
|
}
|
|
|
|
if($cyear < 0) {
|
|
|
|
$cyear = abs($cyear);
|
|
|
|
return "$cyear BCE";
|
|
|
|
} else {
|
2015-07-17 04:53:37 -07:00
|
|
|
return "$cyear";
|
2013-11-17 15:55:57 -08:00
|
|
|
}
|
|
|
|
}
|
2015-07-17 05:49:50 -07:00
|
|
|
# formats the result that should be returned
|
|
|
|
sub format_result {
|
|
|
|
my ($plaintext, $title, $subtitle) = @_;
|
|
|
|
|
|
|
|
return $plaintext,
|
|
|
|
structured_answer => {
|
|
|
|
id => "leap_year",
|
|
|
|
name => "Answer",
|
|
|
|
data => {
|
|
|
|
title => $title || $plaintext,
|
|
|
|
subtitle => $subtitle
|
|
|
|
},
|
|
|
|
templates => {
|
|
|
|
group => "text",
|
|
|
|
moreAt => 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-17 15:55:57 -08:00
|
|
|
handle remainder => sub {
|
2015-01-02 03:23:54 -08:00
|
|
|
|
2015-01-02 04:15:44 -08:00
|
|
|
my $year = (localtime)[5] + 1900;
|
2015-07-17 05:49:50 -07:00
|
|
|
my @result;
|
2015-01-02 03:23:54 -08:00
|
|
|
|
2014-01-25 13:16:54 -08:00
|
|
|
if ($_ =~ /(last|previous) ([0-9][0-9]?)$/i) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my @years = search_leaps($2, -1, 0, $year);
|
2013-11-17 15:55:57 -08:00
|
|
|
@years = map(format_year, @years);
|
2014-01-28 14:09:49 -08:00
|
|
|
my $pretty_years = join(', ', @years);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("The last $2 leap years were $pretty_years", $pretty_years, "The last $2 leap years");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2014-01-25 13:16:54 -08:00
|
|
|
} elsif ($_ =~ /(next|future) ([0-9][0-9]?)$/i) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my @years = search_leaps($2, 1, 0, $year);
|
2013-11-17 15:55:57 -08:00
|
|
|
@years = map(format_year, @years);
|
2014-01-28 14:09:49 -08:00
|
|
|
my $pretty_years = join(', ', @years);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("The $1 $2 leap years will be $pretty_years", $pretty_years, "The $1 $2 leap years");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2014-01-25 15:15:19 -08:00
|
|
|
} elsif ($_ =~ /^(after|before) ([0-9]+) ?(ad|bce|bc|ce)?$/) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my $cyear = $2;
|
2013-11-17 16:44:19 -08:00
|
|
|
my $direction = $1;
|
2013-11-17 16:39:36 -08:00
|
|
|
if(defined($3) && $3 =~ /^(bce|bc)$/i) {
|
|
|
|
$cyear = -$cyear;
|
|
|
|
}
|
|
|
|
my $dir = 1;
|
2014-01-25 15:15:19 -08:00
|
|
|
if($direction eq "before") {
|
2013-11-17 16:39:36 -08:00
|
|
|
$dir = -1;
|
|
|
|
}
|
|
|
|
my @years = search_leaps(5, $dir, 0, $cyear);
|
|
|
|
@years = map(format_year, @years);
|
2014-01-28 14:09:49 -08:00
|
|
|
my $pretty_years = join(', ', @years);
|
2013-11-17 16:39:36 -08:00
|
|
|
my $pretty_year = format_year($cyear);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("The 5 leap years $direction $pretty_year are $pretty_years",
|
|
|
|
$pretty_years,
|
|
|
|
"The 5 leap years $direction $pretty_year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-17 16:08:06 -08:00
|
|
|
} elsif ($_ =~ /(next|future|upcoming)$/i) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my ($nyear) = search_leaps(1, 1, 0, $year);
|
2013-11-17 15:55:57 -08:00
|
|
|
$nyear = format_year($nyear);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("$nyear will be the $1 leap year", $nyear, "The $1 leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-17 16:08:06 -08:00
|
|
|
} elsif ($_ =~ /(latest|last|previous)$/i) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my ($pyear) = search_leaps(1, -1, 0, $year);
|
2013-11-17 15:55:57 -08:00
|
|
|
$pyear = format_year($pyear);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("$pyear was the $1 leap year", $pyear, "The $1 leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-17 16:08:06 -08:00
|
|
|
} elsif ($_ =~ /(most recent)$/i) {
|
2013-11-17 16:39:36 -08:00
|
|
|
my ($ryear) = search_leaps(1, -1, 1, $year);
|
2013-11-17 15:55:57 -08:00
|
|
|
$ryear = format_year($ryear);
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("$ryear is the $1 leap year", $ryear, "The $1 leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2014-01-25 15:15:19 -08:00
|
|
|
} elsif($_ =~ /^(was|is|will) ([0-9]+) ?(ad|bce|bc|ce)?( be)? a$/i) {
|
2013-11-17 16:08:06 -08:00
|
|
|
my $cyear = $2;
|
|
|
|
if(defined($3) && $3 =~ /^(bce|bc)$/i) {
|
2013-11-01 09:09:57 -07:00
|
|
|
$cyear = -$cyear;
|
|
|
|
}
|
2013-11-17 15:55:57 -08:00
|
|
|
my $fyear = format_year($cyear);
|
2015-01-02 03:23:54 -08:00
|
|
|
my $tense = find_tense($cyear, $year);
|
2013-11-01 09:09:57 -07:00
|
|
|
if(isleap($cyear)) {
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("Yes! $fyear $is_tense{$tense} a leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-01 09:09:57 -07:00
|
|
|
} else {
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("No. $fyear $is_not_tense{$tense} a leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-01 09:09:57 -07:00
|
|
|
}
|
2013-11-21 16:46:56 -08:00
|
|
|
} elsif($_ =~ /^is it( now | currently)? a|are we in a$/i) {
|
2013-11-17 15:55:57 -08:00
|
|
|
my $fyear = format_year($year);
|
2013-11-01 09:09:57 -07:00
|
|
|
if(isleap($year)) {
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("Yes! $fyear is a leap year");
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2013-11-01 09:09:57 -07:00
|
|
|
} else {
|
2015-07-14 23:55:22 -07:00
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
@result = format_result("No. $fyear is not a leap year"),
|
2015-07-14 23:55:22 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-17 05:49:50 -07:00
|
|
|
return @result;
|
2013-11-01 09:09:57 -07:00
|
|
|
};
|
|
|
|
|
2015-07-17 04:53:37 -07:00
|
|
|
1;
|