current date - 8 months in perl script

I have a requirement as follows.

when i pass a date to the perl script, it has to calculate the current date - 8 months and output the date back to the shell script in date format (YYYY-MM-DD).

Current date - 8 months is not constant.. because leap year, and the months jan, mar, may,.... has 31 days and april, june,.... has 30 days.

The output should be accurate.

Can anyone provide a solution for this issue.

Thanks
Krishnakanth

use Date::Calc qw(Add_Delta_YM);

my $date_input = '2000-08-01';

my @date = split /-/ ,$date_input;

($year,$month,$day) =  Add_Delta_YM($date[0],$date[1],$date[2],0,-8);

if ($month < 10) {
	$month = 0 . $month;
}
return $year . '-' . $month . '-' . $day;

try that

Try:

#!/usr/bin/perl
use POSIX;
my @t = localtime(time);
print strftime("%Y-%m-%d\n", localtime(mktime(0,0,0,$t[3],$t[4]-8,$t[5],0,0)));

---------- Post updated at 11:58 AM ---------- Previous update was at 11:19 AM ----------

Or if you want to read date from stdin, validate and then output 8 months earlier:

8month.pl:

#!/usr/bin/perl
use Time::Local 'timelocal';
use POSIX;
my $year, $month, $day;
while (my $ln = <STDIN>) {
  if($ln =~ /(\d\d\d\d).(\d\d).(\d\d)/) {
    $ln =~ s/(\d\d\d\d).(\d\d).(\d\d)/\1 \2 \3/;
    ($year, $month, $day) = split(/\s/, $ln);
    break unless timelocal(0,0,0,$day,$month-1,$year);
  }
}
print strftime("%Y-%m-%d\n", localtime(mktime(0,0,0,$day,$month-9,$year-1900,0,0))) unless ($day == 0);

Examples:

$ echo "2012-08-31" | ./8month.pl
2011-12-31
 
$ echo "2012-18-31" | ./8month.pl
Month '17' out of range 0..11 at ./8month.pl line 9
 
$ echo "2012/01/01" | ./8month.pl
2011-05-01
 
$ echo "2012-10-30" | ./8month.pl
2012-03-01

If perl is not mandatory and if you have GNU date, you could do this:

date -d "-8 months" +%Y-%m-%d

Using dateutils this would be:

dadd today -8mo
=>
2011-12-31