use Time::Local qw(); use POSIX qw(); my %args = @macro_args; my ( $t2arr, $arr2t ) = ( sub { gmtime($_[0]) }, sub { Time::Local::timegm(@_) } ); if ( my $time_standard = $args{time_standard} ) { if ( $time_standard eq 'local' ) { ( $t2arr, $arr2t ) = ( sub { localtime($_[0]) }, sub { Time::Local::timelocal(@_) } ); } elsif ( $time_standard eq 'gm' ) { } else { die "date_8 'time_standard' must be either 'local' or 'gm'. 'gm' is the default.\n"; } } my @month_lenths = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); my @leap_month_lenghts = @month_lenths; $leap_month_lenghts[1]++; $self->add_hook ( 'validate_hook', sub { $_[1] =~ /^(\d{4})(\d{2})(\d{2})$/ or die "$_[1] is not a valid date"; # quick month check $2 < 13 && $2 > 0 or die "$_[1] is not a valid date"; # quick day check $3 < 32 && $3 > 0 or die "$_[1] is not a valid date"; my $is_leap; if($1 % 400 == 0) { $is_leap = 1; } elsif ($1 % 100 == 0) { undef $is_leap } elsif ($1 % 4 == 0) { $is_leap = 1; } my $last_day_in_month = $is_leap ? $leap_month_lenghts[ $2 - 1 ] : $month_lenths[ $2 - 1 ]; die "$_[1] not a valid date\n" if $last_day_in_month < $3; return; } ); $self->add_method ( 'days_add', sub { $_[0]->get() =~ /^(\d{4})(\d{2})(\d{2})$/; my ($y, $m, $d) = ( $1, $2, $3 ); my $time = $arr2t->( 0, 0, 0, $d, $m-1, $y ); my $seconds_offset = 86400 * ( $_[1] || 0 ); my $new_time = $time + $seconds_offset; my @tm = $t2arr->( $new_time ); return ($tm[5]+1900) . substr("00".($tm[4]+1),-2) . substr("00".$tm[3],-2); } ); $self->add_method ( 'today', sub { my $day_offset = $_[1] || 0; my @tm = $t2arr->( time() + $day_offset * 86400 ); return ($tm[5]+1900) . substr("00".($tm[4]+1),-2) . substr("00".$tm[3],-2); } ); $self->add_method ( 'diff_today', sub { $_[0]->get() =~ /^(\d{4})(\d{2})(\d{2})$/; my ($y, $m, $d) = ( $1, $2, $3 ); my $time = $arr2t->( 0, 0, 0, $d, $m-1, $y ); return POSIX::floor ( (time() - $time) / 86400 ); } ); $self->add_method ( 'gmtime', sub { my ( $self, $days_offset ) = @_; $self->get() =~ /^(\d{4})(\d{2})(\d{2})$/; my ($y, $m, $d) = ( $1, $2, $3 ); my $time = $arr2t->( 0, 0, 0, $d, $m-1, $y ); if ( $days_offset ) { $time += $days_offset * (60*60*24); } my @tm = $t2arr->( $time ); return @tm; } ); $self->add_method ( 'timegm', sub { my ( $self, $time ) = @_; my @tm = $t2arr->( $time ); return ($tm[5]+1900) . substr("00".($tm[4]+1),-2) . substr("00".$tm[3],-2); } );