2012-03-30 13 views
9

C'è un modo per capire il primo giorno del mese (giorno min) e l'ultimo giorno di un mese (giorno max), dato il mese come input, usando DateTime in perl?Come posso ottenere il primo e l'ultimo giorno del mese con Perl's DateTime?

Finora, ho capito come passare un primo appuntamento, l'ultimo giorno per darmi una serie di giorni.

Ma quello che voglio fare ora è passare un mese come argomento, diciamo 201203 e restituire min, maxday.

È possibile con DateTime?

Inoltre, desidero modificare la maschera del formato della data da AAAAMMGG a AAAA-MM-GG.

use strict; 
    use warnings; 
    use DateTime; 

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

    my ($first_date,$last_date)[email protected]; 

    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); 
} 

Risultati attesi:

2012-03-01 
2012-03-31 
+3

Il giorno minimo è sempre 1! – theglauber

risposta

14

DateTime data l'matematica per voi. Si può dire ymd quale personaggio si desidera utilizzare come separatore:

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

Ci sono molti esempi in "Last day of the month. Any shorter" su PerlMonks, che ho trovato da Googling "perl datetime last day of month".


Ed ecco un esempio Time::Moment. Si tratta di una più snella, sottoinsieme più veloce di 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'); 
6

Primo giorno:

$dt->set_day(1); 

Ultimo giorno:

$dt->set_day(1)->add(months => 1)->subtract(days => 1); 
+8

Non dimenticare di chiamare 'clone' se vuoi evitare di cambiare' $ dt'. – ikegami

8

In alternativa c'è il modulo Perl Time::Piece nucleo.

per il mese corrente e l'anno:

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

Più in generale, qualcosa di simile:

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 
9

E 'sorprendente, che né DateTime esempio utilizza la funzione di costruzione speciale last_day_of_month per questo (ad esempio per gentile concessione di 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('-'); 
0

Mentre il DateTime la classe offre un costruttore per fare ciò, il modo più efficace per ottenere l'ultimo giorno del mese da un oggetto DateTime esistente è di richiedere all'oggetto di calcolarlo. La classe espone un metodo non documentato _month_length() che calcola l'ultimo giorno del mese in modo molto efficiente. Con il vostro oggetto DateTime chiamato $ data, si può provare

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

Questo metodo è documentato, in modo che possono o non possono essere supportate da una versione di DateTime. Usare con cautela.

Problemi correlati