package Meetup; use strict; use warnings; use Exporter qw; our @EXPORT_OK = qw; use Date::Calc qw( Nth_Weekday_of_Month_Year Days_in_Month ); sub meetup { my ($desc) = @_; my %input; my %day_number; my %month_number; my %week_number; @input{ qw( week day_of_week of month year ) } = split / /, $desc; @day_number{ qw( Monday Tuesday Wednesday Thursday Friday Saturday Sunday ) } = ( 1 .. 7 ); @month_number{ qw( January February March April May June July August September October November December ) } = ( 1 .. 12 ); @week_number{ qw( First Second Third Fourth Fifth Last Teenth ) } = ( 1 .. 7 ); my $month_num = $month_number{ $input{ month } }; my $day_num = $day_number{ $input{ day_of_week } }; my $week_num = $week_number{ $input{ week } }; # if we are asked to find the last day in the month if ( $input{ week } eq 'Last' ) { my $days_in_month = Days_in_Month( $input{ year }, $month_num ); my ($year, $month, $day) = Nth_Weekday_of_Month_Year( $input{ year }, $month_num, $day_num, 3 # find the day of month of the third occurrence of the day ); # $day now holds the day of the month of the third occurence of the day # Check what would be the date 2 weeks from that day. # If the date exceeds the number of days in the month, then the last # occurrence of that day occurs in week 4. Otherwise, it occurs in # week 5. $week_num = $day + 14 > $days_in_month ? 4 : 5; } # find the "teenth" day if ( $input{ week } eq 'Teenth' ) { foreach my $possible_week ( 2 .. 4) { my ($year, $month, $day) = Nth_Weekday_of_Month_Year( $input{ year }, $month_num, $day_num, $possible_week ); if ( $day > 12 and $day < 20 ) { $week_num = $possible_week; last; } } } my ($year, $month, $day) = Nth_Weekday_of_Month_Year( $input{ year }, $month_num, $day_num, $week_num ) if $week_num < 6; my $result = sprintf( "%04d-%02d-%02d", $year, $month, $day ); return $result; } 1;