# a core method determine start/end dates of prior months
use strict; use warnings;
use Time::Local;
my @startend; # [0] is current noncompleted month others are full mo
+nths back
# in each of those the sub elements are
# [0] yyyy mm
# [1] is start yyyy mm dd
# [2] is end yyyy mm dd
my $date;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(
+time) ;
# move to noon so DST changes dont kill ya
my $now_fix12=timelocal( 0, 0, 12, $mday, $mon, $year);
$date=$now_fix12;
my $back=24;
for my $m (0..$back) {push @startend,['']};
my $todo=0;
my $doing;
my ($ym,$ymd);
$doing=$startend[$todo];
($date,$ym,$ymd)=getparts($date);
startup($doing,$ym,$ymd);
while (1) {
($date,$ym,$ymd)=getparts($date);
# print $ymd."\n";
unless ($doing->[0] eq $ym) {
$todo++;
last if ($todo>$back);
$doing=$startend[$todo];
startup($doing,$ym,$ymd);
}
else {$doing->[1]=$ymd; }
} # while
for my $doing (@startend) {
print join(' | ',@$doing)."\n";
}
exit;
sub startup {
my $doing=shift;
my $ym=shift;
my $ymd=shift;
$doing->[0]=$ym;
$doing->[1]=$ymd;
$doing->[2]=$ymd;
} # startup
sub getparts {
my $date=shift;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(
+$date) ;
my $ymd=sprintf('%4d %02d %02d',$year+1900,$mon+1,$mday);
my $ym=substr($ymd,0,7);
$date=$date-24*60*60;
return ($date,$ym,$ymd);
}
Result
2017 06 | 2017 06 01 | 2017 06 23
2017 05 | 2017 05 01 | 2017 05 31
2017 04 | 2017 04 01 | 2017 04 30
2017 03 | 2017 03 01 | 2017 03 31
2017 02 | 2017 02 01 | 2017 02 28
2017 01 | 2017 01 01 | 2017 01 31
2016 12 | 2016 12 01 | 2016 12 31
2016 11 | 2016 11 01 | 2016 11 30
2016 10 | 2016 10 01 | 2016 10 31
2016 09 | 2016 09 01 | 2016 09 30
2016 08 | 2016 08 01 | 2016 08 31
2016 07 | 2016 07 01 | 2016 07 31
2016 06 | 2016 06 01 | 2016 06 30
2016 05 | 2016 05 01 | 2016 05 31
2016 04 | 2016 04 01 | 2016 04 30
2016 03 | 2016 03 01 | 2016 03 31
2016 02 | 2016 02 01 | 2016 02 29
2016 01 | 2016 01 01 | 2016 01 31
2015 12 | 2015 12 01 | 2015 12 31
2015 11 | 2015 11 01 | 2015 11 30
2015 10 | 2015 10 01 | 2015 10 31
2015 09 | 2015 09 01 | 2015 09 30
2015 08 | 2015 08 01 | 2015 08 31
2015 07 | 2015 07 01 | 2015 07 31
2015 06 | 2015 06 01 | 2015 06 30
Note that element 0 in @startup is the current non completed month, others are full months back
If you are just dealing with days, $date=$date-24*60*60; is fine if $date starts at noon.
|