Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go back months in Perl taking account of different days in month?

I was wondering if there is an in-built Perl function that adjusts the date if you take a month from it. E.g. if date is the 31st, it will adjust to be the end of the previous month if it doesn't have 31 days.

I would just change it to 30th easily if it weren't for the months with 31 days next to each other (Dec/Jan, Jul/Aug) and February. I just want to store the date a certain amount of time away from the current date, e.g.

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

$current_date = join("-", (1900+$year), ($mon+1), $mday);
$one_month_ago = join("-", (1900+$year), ($mon), $mday);
$one_year_ago = join("-", (1899+$year), ($mon+1), $mday);

I can deal with the February instance as it only applies to years, but if this was taken on the 31st December 2012 then taking away a month would mean 31st Nov 2012, which of course didn't exist. I thought I would ask if there was a function before complicating things for myself... thanks :)

like image 247
dgBP Avatar asked Aug 29 '12 11:08

dgBP


1 Answers

DateTime is not a built-in module, but once you've installed it, it makes this math trivial:

#!/usr/bin/perl
use strict;
use warnings;

use feature qw( say );
use DateTime;

my $dt = DateTime->now;
say $dt->ymd;

$dt->truncate( to => month );

say $dt->ymd;

$dt->add( days => -1 );
say $dt->ymd;

foreach ( 1 .. 12 ) { 
    $dt->add( months => -1 );
    say $dt->ymd;
} 

When I run this today (Aug 29, 2012) I get the following output:

[~] $ perl dt.pl 
2012-08-29
2012-08-01
2012-07-31
2012-06-30
2012-05-31
2012-04-30
2012-03-31
2012-02-29
2012-01-31
2011-12-31
2011-11-30
2011-10-31
2011-09-30
2011-08-31
2011-07-31
like image 159
oalders Avatar answered Nov 15 '22 00:11

oalders