Perhaps I'm missing something, but you're doing way too
many calculations in there. You're taking epoch seconds, computing the date in month, day, and year, then converting back to epoch seconds?
In addition, you get a warning:
# "my" variable $date masks earlier declaration in same scope.
You declared $date twice as a my variable.
Try this:
sub calcDate {
my $offset = shift;
my($mday, $mon, $year) =
(localtime(time - $offset * 86400))[3..5];
return sprintf "%04s-%02s-%02s", $year + 1900,
$mon + 1, $mday;
}