Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the first and last day of the month with Perl's DateTime?

Tags:

datetime

perl

Is there a way to figure out the first day of the month (min day) and the last day of a month (max day), given the month as input, using DateTime in perl?

So far, I figured out how to pass in a first date, last date to give me a range of days.

But what I want to do now is just pass in a month as an argument, say 201203 and return min, maxday.

Is that possible with DateTime?

Also, I want to change the date format mask from YYYYMMDD to YYYY-MM-DD.

    use strict;
    use warnings;
    use DateTime;

    unless(@ARGV==2)
    {
        print "Usage: myperlscript first_date last_date\n";
        exit(1);
    }

    my ($first_date,$last_date)=@ARGV;

    my $date=DateTime->new(
    {
      year=>substr($first_date,0,4),
      month=>substr($first_date,4,2),
      day=>substr($first_date,6,2)
    });


while($date->ymd('') le $last_date)
{
  print $date->ymd('') . "\n";
  #$date->add(days=>1); #every day
  $date->add(days=>30);
}

Expected Results:

2012-03-01
2012-03-31
like image 560
cjd143SD Avatar asked Mar 30 '12 20:03

cjd143SD


People also ask

How do I get the last day of the month in Perl?

Call it like this: $lastday = LastDayOfMonth($year,$month);

How do I compare two dates in Perl?

If the dates are ISO-8601 (ie, YYYY-MM-DD) and you do not need to validate them, you can compare lexicographically (ie, the lt and gt operators.) If you need to validate the dates, manipulate the dates, or parse non standard formats -- use a CPAN module.


2 Answers

DateTime does date math for you. You can tell ymd which character you want to use as the separator:

use DateTime;

my( $year, $month ) = qw( 2012 2 );

my $date = DateTime->new(
    year  =>  $year,
    month => $month,
    day   => 1,
);

my $date2 = $date->clone;

$date2->add( months => 1 )->subtract( days => 1 );

say $date->ymd('-');
say $date2->ymd('-');

There are many examples in "Last day of the month. Any shorter" on Perlmonks, which I found by Googling "perl datetime last day of month".


And here's a Time::Moment example. It's a leaner, faster subset of DateTime:

use v5.10;
use Time::Moment;

my( $year, $month ) = qw( 2012 2 );

my $tm = Time::Moment->new(
    year  =>  $year,
    month => $month,
    day   => 1,
);

my $tm2 = $tm->plus_months( 1 )->minus_days( 1 );

say $tm->strftime('%Y-%m-%d');
say $tm2->strftime('%Y-%m-%d');
like image 77
brian d foy Avatar answered Sep 17 '22 23:09

brian d foy


It is surprising, that neither DateTime example uses the special constructor last_day_of_month for that (example courtesy of brian d foy):

use DateTime;
use strict;
use 5.010;

my( $year, $month ) = qw( 2012 2 );

my $date = DateTime->new(
    year  =>  $year,
    month => $month,
    day   => 1,
);

my $date2 = DateTime->last_day_of_month(  
    year  =>  $date->year,
    month => $date->month,
);

say $date->ymd('-');
say $date2->ymd('-');
like image 42
w.k Avatar answered Sep 19 '22 23:09

w.k