#!/usr/bin/perl use strict; use warnings; use Date::Calc qw(:all); use Lingua::EN::Inflect qw(ORD); sub commify { local $_ = shift; 1 while s/^([-+]?\d+)(\d{3})/$1,$2/; return $_; } sub birth_year { print "What year were you born? (YYYY) "; chomp(my $b_year = <>); # Checking for a 4 digit year. if ($b_year !~ /\d{4}/) { print "Sorry, please use the full year.\n"; $b_year = birth_year(); } return $b_year; } sub birth_month { print "What month were you born? (MM or name) "; chomp(my $b_month = <>); # This is language specific for English. if ($b_month =~ /[a-z]+/i) { $b_month = Decode_Month($b_month,1); # If the month doesn't match, it will try again. # Decode_Month had error checking in mind. if ($b_month =~ /0/) { print "Sorry, that is not a month.\n"; $b_month = birth_month(); } } return $b_month; } sub birth_day { my ($b_year,$b_month) = @_; my $month_name = Month_to_Text($b_month); print "What day were you born? (DD) "; chomp(my $b_day = <>); # Checking for 0. if (!$b_day or $b_day == 0) { print "Sorry, you did not specify a date.\n"; $b_day = birth_day($b_year,$b_month); } # Checking days for February first. elsif ($b_month =~ /^(0?[2])$/) { if ($b_year % 4 == 0 && $b_day > 29) { print "Sorry, $month_name in $b_year only had 29 days.\n"; $b_day = birth_day($b_year,$b_month); } elsif ($b_day > 28) { print "Sorry, $month_name in $b_year only had 28 days.\n"; $b_day = birth_day($b_year,$b_month); } } # Checking for the months with 31 days. elsif ($b_month =~ /^(0?[13578]|1[02])$/ && $b_day > 31) { print "Sorry, $month_name only has 31 days.\n"; $b_day = birth_day($b_year,$b_month); } # Checking for the months with 30 days. elsif ($b_month =~ /^(0?[469]|11)$/ && $b_day > 30) { print "Sorry, $month_name only has 30 days.\n"; $b_day = birth_day($b_year,$b_month); } return $b_day; } # Let's personalize it a bit. :) print "What's your name? "; chomp(my $name = <>); my $birth_year = birth_year(); my $birth_month = birth_month(); my $birth_day = birth_day($birth_year,$birth_month); my $year = (localtime)[5] + 1900; my $month = (localtime)[4] + 1; my $day = (localtime)[3]; # The following counts how many birthdays there has been. # It also figures out the next year for a birthday. # I'm still working on the kinks in the next birthday. my $birthdays; my $next_year; if ($birth_month > $month) { $birthdays = $year - $birth_year - 1; $next_year = $year; } else { if ($birth_day > $day) { $birthdays = $year - $birth_year - 1; $next_year = $year; } else { $birthdays = $year - $birth_year; $next_year = $year + 1; } } my @birth = ($birth_year,$birth_month,$birth_day); my @next_bday = ($next_year,$birth_month,$birth_day); my @today = ($year,$month,$day); my $days_alive = Delta_Days(@birth,@today); my $days_til_next_bday = Delta_Days(@today,@next_bday); my $unbirthdays = ORD(commify($days_alive - $birthdays)); print "\nHappy $unbirthdays unbirthday, $name!\n"; print "You have $days_til_next_bday days until your next birthday.\n";