Как я могу получить первый и последний день месяца с помощью Perl's DateTime? - PullRequest
12 голосов
/ 31 марта 2012

Есть ли способ определить первый день месяца (минимальный день) и последний день месяца (максимальный день), учитывая месяц в качестве входных данных, используя DateTime в perl?

До сих пор я выяснил, как передать первое свидание, последнее свидание, чтобы дать мне диапазон дней.

Но то, что я хочу сейчас сделать, это просто передать месяц как аргумент, скажем 201203 и возврат мин., Макс.

Возможно ли это с 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 ]

15 голосов
/ 31 марта 2012

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, который я нашел по Googling "perl datetime последний день месяца" .

<Ч />

А вот пример Время :: Момент . Это более быстрое и быстрое подмножество 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');
12 голосов
/ 31 марта 2012

Удивительно, что ни один из примеров 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('-');
8 голосов
/ 31 марта 2012

В качестве альтернативы есть основной модуль 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
6 голосов
/ 31 марта 2012

Первый день:

$dt->set_day(1);

Последний день:

$dt->set_day(1)->add( months => 1 )->subtract( days => 1 );
1 голос
/ 08 августа 2017

В то время как класс DateTime предлагает конструктор для этого, наиболее эффективный способ получить последний день месяца из существующего объекта DateTime - запросить объект для его вычисления. Класс предоставляет недокументированный метод _month_length (), который очень эффективно вычисляет последний день месяца. С вашим объектом DateTime с именем $ date вы можете попробовать

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

Этот метод недокументирован, поэтому он может поддерживаться или не поддерживаться в вашей версии DateTime. Используйте с осторожностью.

UPD

Начиная с версии 1.144 DateTime начинает поддерживать month_lenth

История вопроса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...