2012-05-08 19:01:16 -07:00
|
|
|
package DDG::Goodie::DateMath;
|
2014-08-20 11:45:33 -07:00
|
|
|
# ABSTRACT: add/subtract days/weeks/months/years to/from a date
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2015-02-22 12:09:29 -08:00
|
|
|
use strict;
|
2012-05-08 19:01:16 -07:00
|
|
|
use DDG::Goodie;
|
2014-08-11 14:58:28 -07:00
|
|
|
with 'DDG::GoodieRole::Dates';
|
|
|
|
use DateTime::Duration;
|
2012-05-20 09:15:56 -07:00
|
|
|
use Lingua::EN::Numericalize;
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2015-01-15 19:00:37 -08:00
|
|
|
triggers any => qw( plus minus + - date day week month year days weeks months years);
|
2012-05-23 19:05:08 -07:00
|
|
|
|
2012-05-08 19:01:16 -07:00
|
|
|
zci is_cached => 1;
|
|
|
|
zci answer_type => 'date_math';
|
|
|
|
|
2012-11-06 13:01:09 -08:00
|
|
|
primary_example_queries 'Jan 1 2012 plus 32 days';
|
2014-12-24 23:33:53 -08:00
|
|
|
secondary_example_queries '1/1/2012 plus 5 months', 'January first minus ten days', 'in 5 weeks', '2 weeks ago', '1 month from today';
|
2012-11-06 13:01:09 -08:00
|
|
|
description 'calculate the date with an offset';
|
|
|
|
name 'DateMath';
|
|
|
|
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/DateMath.pm';
|
|
|
|
category 'time_sensitive';
|
2012-11-06 21:59:54 -08:00
|
|
|
topics 'everyday';
|
2012-11-06 13:01:09 -08:00
|
|
|
attribution github => ['http://github.com/cj01101', 'cj01101'];
|
|
|
|
|
2014-08-31 13:33:20 -07:00
|
|
|
my $datestring_regex = datestring_regex();
|
2012-11-06 13:01:09 -08:00
|
|
|
|
2012-05-08 19:01:16 -07:00
|
|
|
handle query_lc => sub {
|
2014-08-11 14:58:28 -07:00
|
|
|
my $query = $_;
|
2014-12-24 23:05:12 -08:00
|
|
|
|
2014-12-27 01:44:57 -08:00
|
|
|
my $relative_regex = qr!(?<number>\d+|[a-z\s-]+)\s+(?<unit>(?:day|week|month|year)s?)!;
|
2014-12-25 08:23:31 -08:00
|
|
|
|
2014-12-27 01:44:57 -08:00
|
|
|
return unless $query =~ qr!^(?:date\s+)?(
|
|
|
|
(?<date>$datestring_regex)(?:\s+(?<action>plus|\+|\-|minus)\s+$relative_regex)?|
|
|
|
|
$relative_regex\s+(?<action>from)\s+(?<date>$datestring_regex)?
|
|
|
|
)$!x;
|
|
|
|
|
|
|
|
if (!exists $+{'number'}) {
|
|
|
|
my $out_date = date_output_string(parse_datestring_to_date($+{'date'}));
|
|
|
|
return $out_date,
|
|
|
|
structured_answer => {
|
|
|
|
input => [$+{'date'}],
|
2015-01-15 17:54:04 -08:00
|
|
|
operation => 'Date math',
|
2014-12-27 01:44:57 -08:00
|
|
|
result => $out_date
|
|
|
|
};
|
2014-12-24 23:05:12 -08:00
|
|
|
}
|
2014-12-27 01:44:57 -08:00
|
|
|
|
|
|
|
my $input_date = parse_datestring_to_date($+{date});
|
|
|
|
my $input_number = str2nbr($+{number});
|
|
|
|
my $unit = $+{unit};
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2012-05-09 19:23:15 -07:00
|
|
|
# check/tweak other (non-date) input
|
2012-05-08 19:01:16 -07:00
|
|
|
my %action_map = (
|
|
|
|
plus => '+',
|
|
|
|
'+' => '+',
|
|
|
|
minus => '-',
|
|
|
|
'-' => '-',
|
2014-12-27 01:44:57 -08:00
|
|
|
from => '+'
|
2012-05-08 19:01:16 -07:00
|
|
|
);
|
2014-12-27 01:44:57 -08:00
|
|
|
my $action = $action_map{$+{action}} || return;
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2012-05-09 19:23:15 -07:00
|
|
|
my $number = $action eq '-' ? 0 - $input_number : $input_number;
|
2012-05-08 19:01:16 -07:00
|
|
|
|
|
|
|
$unit =~ s/s$//g;
|
2014-10-28 11:36:15 -07:00
|
|
|
|
2014-08-11 14:58:28 -07:00
|
|
|
my ($years, $months, $days, $weeks) = (0, 0, 0, 0);
|
2014-10-06 03:26:19 -07:00
|
|
|
$years = $number if $unit eq "year";
|
|
|
|
$months = $number if $unit eq "month";
|
|
|
|
$days = $number if $unit eq "day";
|
|
|
|
$days = 7 * $number if $unit eq "week";
|
2014-10-28 11:36:15 -07:00
|
|
|
|
2014-08-11 14:58:28 -07:00
|
|
|
my $dur = DateTime::Duration->new(
|
|
|
|
years => $years,
|
|
|
|
months => $months,
|
|
|
|
days => $days
|
|
|
|
);
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2014-10-06 03:26:19 -07:00
|
|
|
$unit .= 's' if $input_number > 1; # plural?
|
|
|
|
my $out_date = date_output_string($input_date->clone->add_duration($dur));
|
|
|
|
my $in_date = date_output_string($input_date);
|
|
|
|
my $out_action = "$action $input_number $unit";
|
2012-05-08 19:01:16 -07:00
|
|
|
|
2014-10-06 03:26:19 -07:00
|
|
|
return "$in_date $out_action is $out_date",
|
|
|
|
structured_answer => {
|
|
|
|
input => [$in_date . ' ' . $out_action],
|
2015-01-08 23:59:26 -08:00
|
|
|
operation => 'Date math',
|
2014-10-06 03:26:19 -07:00
|
|
|
result => $out_date
|
|
|
|
};
|
2012-05-08 19:01:16 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
1;
|