首页 文章

如何使用Perl的DateTime获得本月的第一天和最后一天?

提问于
浏览
11

有没有办法找出月份的第一天(最小的一天)和一个月的最后一天(最大的一天),给定月份作为输入,在perl中使用 DateTime

到目前为止,我想出了如何传递第一个日期,最后一个日期给我一系列日子 .

但我现在要做的只是作为一个论点传递一个月,比如 201203 并返回min,maxday .

这可能与DateTime有关吗?

另外,我想将日期格式掩码从YYYYMMDD更改为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);
}

预期成绩:

2012-03-01
2012-03-31

5 回答

  • 8

    DateTime为你做日期数学 . 你可以告诉 ymd 你想用哪个字符作为分隔符:

    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('-');
    

    关于Perlmonks的"Last day of the month. Any shorter"中有很多例子,我通过Googling "perl datetime last day of month"找到了这些例子 .


    这是一个Time::Moment的例子 . 它是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');
    
  • 15

    令人惊讶的是, DateTime 示例都没有使用特殊构造函数 last_day_of_month (示例由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('-');
    
  • 11

    作为替代方案,有核心Perl模块 Time::Piece .

    对于当前月份和年份:

    perl -MTime::Piece -wE '$t=localtime;say $t->month_last_day'
    31
    

    更一般地说,类似于:

    use 5.010;
    use Time::Piece;
    my $MY = shift || die "Month and Year expected\n";
    my $t  = Time::Piece->strptime($MY, "%m%Y");
    say $t->month_last_day;
    
    $ ./mycode 022012
    29
    
  • 1

    第一天:

    $dt->set_day(1);
    

    最后一天:

    $dt->set_day(1)->add( months => 1 )->subtract( days => 1 );
    
  • 6

    虽然DateTime类提供了一个构造函数来执行此操作,但从现有DateTime对象获取月份最后一天的最有效方法是请求对象计算它 . 该类公开了一个未记录的方法_month_length(),它非常有效地计算了该月的最后一天 . 使用名为$ date的DateTime对象,您可以尝试

    $date->_month_length($date->year,$date->month);
    

    此方法未记录,因此您的DateTime版本可能支持也可能不支持 . 谨慎使用 .

    UPD

    从v1.144开始DateTime开始支持month_lenth

    History of the issue

相关问题