use strict; use warnings; use POSIX q{strftime}; my @daysInM = ( [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ], [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ], ); # ----- my $rcDay = sub # ----- { my $ts = shift; my $tsStartDay = int( $ts / 86400 ) * 86400; my $tsEndDay = $tsStartDay + 86399; return ( $tsStartDay, $tsEndDay ); }; # ------ my $rcWeek = sub # ------ { my $ts = shift; my ( $t1, $t2 ) = $rcDay->( $ts ); my $wday = ( localtime( $ts ) )[ 6 ]; $t1 -= 86400 * $wday; $t2 += 86400 * ( 6 - $wday ); return ( $t1, $t2 ); }; # ------- my $rcMonth = sub # ------- { my $ts = shift; my ( $t1, $t2 ) = $rcDay->( $ts ); my ( $mday, $mon, $year ) = ( localtime( $ts ) )[ 3 .. 5 ]; $t1 -= 86400 * ( $mday - 1 ); $t2 += 86400 * ( $daysInM[ isLeap( $year + 1900 ) ]->[ $mon ] - $mday ); return ( $t1, $t2 ); }; # ------ my $rcYear = sub # ------ { my $ts = shift; my ( $t1, $t2 ) = $rcDay->( $ts ); my ( $year, $yday ) = ( localtime( $ts ) )[ 5, 7 ]; $t1 -= 86400 * ( $yday ); $t2 += 86400 * ( ( 365, 366 )[ isLeap( $year + 1900 ) ] - $yday - 1 ); return ( $t1, $t2 ); }; my %periodDispatch = ( day => $rcDay, week => $rcWeek, month => $rcMonth, year => $rcYear, ); my $rxValidPeriod = do { local $" = q{|}; qr{(?xi) ^ (?: @{ [ keys %periodDispatch ] } ) $ }; }; my $timeNow = time(); foreach my $t ( $timeNow, $timeNow + 8640000, $timeNow - 20000000 ) { print q{=} x 48, qq{\n}, strftime( qq{\$t - $t - %a %Y-%m-%d.%H:%M:%S %z\n}, localtime( $t ) ), ; foreach my $period ( qw{ day week month year } ) { my ( $t1, $t2 ) = tsPeriod( $t, $period ); print q{-} x 48, qq{\n}, qq{$period:\n}, strftime( qq{\$t1 - $t1 - %a %Y-%m-%d.%H:%M:%S %z\n}, localtime( $t1 ) ), strftime( qq{\$t2 - $t2 - %a %Y-%m-%d.%H:%M:%S %z\n}, localtime( $t2 ) ), ; } } print q{=} x 48, qq{\n}; # -------- sub tsPeriod # -------- { my ( $ts, $period ) = @_; die qq{Timestamp not a +ve integer\n} unless $ts =~ m{^\+?\d+$}; die qq{Period "$period" not recognised\n} unless $period =~ $rxValidPeriod; $period = lc $period; return $periodDispatch{ $period }->( $ts ) ; } # ------ sub isLeap # ------ { my $year = shift; return 0 if $year % 4; return 1 if $year < 1753; return 1 if $year % 100; return 1 unless $year % 400; return 0; }
Here is the output.
================================================ $t - 1194172762 - Sun 2007-11-04.10:39:22 +0000 ------------------------------------------------ day: $t1 - 1194134400 - Sun 2007-11-04.00:00:00 +0000 $t2 - 1194220799 - Sun 2007-11-04.23:59:59 +0000 ------------------------------------------------ week: $t1 - 1194134400 - Sun 2007-11-04.00:00:00 +0000 $t2 - 1194739199 - Sat 2007-11-10.23:59:59 +0000 ------------------------------------------------ month: $t1 - 1193875200 - Thu 2007-11-01.00:00:00 +0000 $t2 - 1196467199 - Fri 2007-11-30.23:59:59 +0000 ------------------------------------------------ year: $t1 - 1167609600 - Mon 2007-01-01.00:00:00 +0000 $t2 - 1199145599 - Mon 2007-12-31.23:59:59 +0000 ================================================ $t - 1202812762 - Tue 2008-02-12.10:39:22 +0000 ------------------------------------------------ day: $t1 - 1202774400 - Tue 2008-02-12.00:00:00 +0000 $t2 - 1202860799 - Tue 2008-02-12.23:59:59 +0000 ------------------------------------------------ week: $t1 - 1202601600 - Sun 2008-02-10.00:00:00 +0000 $t2 - 1203206399 - Sat 2008-02-16.23:59:59 +0000 ------------------------------------------------ month: $t1 - 1201824000 - Fri 2008-02-01.00:00:00 +0000 $t2 - 1204329599 - Fri 2008-02-29.23:59:59 +0000 ------------------------------------------------ year: $t1 - 1199145600 - Tue 2008-01-01.00:00:00 +0000 $t2 - 1230767999 - Wed 2008-12-31.23:59:59 +0000 ================================================ $t - 1174172762 - Sat 2007-03-17.23:06:02 +0000 ------------------------------------------------ day: $t1 - 1174089600 - Sat 2007-03-17.00:00:00 +0000 $t2 - 1174175999 - Sat 2007-03-17.23:59:59 +0000 ------------------------------------------------ week: $t1 - 1173571200 - Sun 2007-03-11.00:00:00 +0000 $t2 - 1174175999 - Sat 2007-03-17.23:59:59 +0000 ------------------------------------------------ month: $t1 - 1172707200 - Thu 2007-03-01.00:00:00 +0000 $t2 - 1175385599 - Sun 2007-04-01.00:59:59 +0100 ------------------------------------------------ year: $t1 - 1167609600 - Mon 2007-01-01.00:00:00 +0000 $t2 - 1199145599 - Mon 2007-12-31.23:59:59 +0000 ================================================
I hope this is of interest.
Cheers,
JohnGG
In reply to Re: Date calculation: start and end of period
by johngg
in thread Date calculation: start and end of period
by dgaramond2
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |