86 lines
2.8 KiB
Perl
Executable File
86 lines
2.8 KiB
Perl
Executable File
use strict;
|
|
|
|
package DDG::Goodie::WeekdaysBetween;
|
|
# ABSTRACT: Give the number of week days between two given dates.
|
|
|
|
use DDG::Goodie;
|
|
with 'DDG::GoodieRole::Dates';
|
|
|
|
triggers start => "weekdays between", "week days between", "weekdays from", "week days from";
|
|
|
|
zci answer_type => "weekdays_between";
|
|
zci is_cached => 0;
|
|
|
|
name 'WeekdaysBetween';
|
|
description 'Calculate the number of weekdays between two dates.';
|
|
category 'calculations';
|
|
topics 'everyday';
|
|
primary_example_queries 'weekdays between 01/31/2000 01/31/2001';
|
|
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/WeekdaysBetween.pm';
|
|
attribution github => ['http://github.com/syst3mw0rm', 'syst3mw0rm'],
|
|
email => ['syst3m.w0rm@gmail.com', 'syst3m.w0rm@gmail.com'];
|
|
|
|
# Wrap the response in html
|
|
sub html_output {
|
|
my ($weekday_count, $start_end_dates) = @_;
|
|
return "<div class='zci--weekdaysbetween'>"
|
|
."<span class='text--primary'>$weekday_count</span><br/>"
|
|
."<span class='text--secondary'>$start_end_dates</span>"
|
|
."</div>";
|
|
}
|
|
|
|
|
|
my $datestring_regex = datestring_regex();
|
|
|
|
handle remainder => sub {
|
|
return unless $_ =~ qr/^($datestring_regex) (?:(?:and|to) )?($datestring_regex)/i;
|
|
my ($start, $end) = (parse_datestring_to_date($1), parse_datestring_to_date($2));
|
|
return unless ($start && $end);
|
|
|
|
# Flip if the dates are the wrong way around
|
|
($end, $start) = ($start, $end) if ( DateTime->compare($start, $end) == 1 );
|
|
|
|
my $weekday_count = delta_weekdays($start, $end);
|
|
|
|
my $start_str = date_output_string($start);
|
|
my $end_str = date_output_string($end);
|
|
|
|
my $verb = $weekday_count == 1 ? 'is' : 'are';
|
|
my $weekday_plurality = $weekday_count == 1 ? 'weekday' : 'weekdays';
|
|
|
|
my $response = "There $verb $weekday_count $weekday_plurality between $start_str and $end_str.";
|
|
|
|
return $response, html => html_output("$weekday_count $weekday_plurality", "between $start_str and $end_str.");
|
|
};
|
|
|
|
# It calculates the number of weekdays between two given dates, both inclusive.
|
|
sub delta_weekdays {
|
|
my ($start, $end) = @_;
|
|
my($day_count, $result, $dow1, $dow2, $wholeweeks, $temp);
|
|
my $difference = $start->delta_days($end);
|
|
|
|
$day_count = $difference->in_units('days') + 1; # always inclusive
|
|
return 0 unless $day_count > 0 ;
|
|
|
|
$dow1 = $start->day_of_week();
|
|
|
|
$wholeweeks = int($day_count / 7);
|
|
$result = $wholeweeks * 5;
|
|
$temp = $day_count - $wholeweeks * 7;
|
|
|
|
$dow2 = $dow1 - 1 + $temp;
|
|
|
|
$dow2 -= 7 if($dow2 > 7);
|
|
|
|
for(;;) {
|
|
$result = $result + 1 if($dow1 < 6);
|
|
last if($dow1 == $dow2);
|
|
$dow1 = $dow1 + 1;
|
|
$dow1 = $dow1 - 7 if($dow1 > 7);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
1;
|