App-Dochazka-REST

 view release on metacpan or  search on metacpan

lib/App/Dochazka/REST/Holiday.pm  view on Meta::CPAN

        end_date => $ARGS{end},
    );
    
    my %retval;

    foreach my $year ( sort( keys %{ $daterange_by_year } ) ) {
        my $holidays = holidays( YEAR => $year, FORMAT => '%Y-%m-%d', WEEKENDS => 1 );
        if ( $year eq $begin_year and $year eq $end_year ) {
            my $tmp_holidays = _eliminate_dates( $holidays, $ARGS{begin}, "before" );
            $holidays = _eliminate_dates( $tmp_holidays, $ARGS{end}, "after" );
            map { $retval{$_} = ''; } @$holidays;
        } elsif ( $year eq $begin_year ) {
            map { $retval{$_} = ''; } @{ _eliminate_dates( $holidays, $ARGS{begin}, "before" ) };
        } elsif ( $year eq $end_year ) {
            map { $retval{$_} = ''; } @{ _eliminate_dates( $holidays, $ARGS{end}, "after" ) };
        } else {
            map { $retval{$_} = ''; } @$holidays;
        }
    }

    return \%retval;
}


=head2 is_weekend

Simple function that takes a canonicalized date string in 
the format YYYY-MM-DD and returns a true or false value 
indicating whether or not the date falls on a weekend.

=cut

sub is_weekend {
    my $cdate = shift;  # cdate == Canonicalized Date String YYYY-MM-DD
    my ( $year, $month, $day ) = $cdate =~ m/(\d{4})-(\d{2})-(\d{2})/;
    my $dow = Day_of_Week( $year, $month, $day );
    return ( $dow == 6 or $dow == 7 )
        ? 1
        : 0;
}


=head2 get_tomorrow

Given a canonicalized date string in the format YYYY-MM-DD, return 
the next date (i.e. "tomorrow" from the perspective of the given date).

=cut

sub get_tomorrow {
    my $cdate = shift;  # cdate == Canonicalized Date String YYYY-MM-DD
    my ( $year, $month, $day ) = $cdate =~ m/(\d{4})-(\d{2})-(\d{2})/;
    my ( $tyear, $tmonth, $tday ) = Add_Delta_Days( $year, $month, $day, 1 );
    return "$tyear-" . sprintf( "%02d", $tmonth ) . "-" . sprintf( "%02d", $tday );
}


=head2 holidays_and_weekends

Given a date range (same as in C<holidays_in_daterange>, above), return
a reference to a hash of hashes that looks like this (for sample dates):

    {
        '2015-01-01' => { holiday => 1 },
        '2015-01-02' => {},
        '2015-01-03' => { weekend => 1 },
        '2015-01-04' => { weekend => 1 },
        '2015-01-05' => {},
        '2015-01-06' => {},
    }

Note that the range is always considered inclusive -- i.e. the bounding
dates of the range will be included in the hash.

=cut

sub holidays_and_weekends {
    my ( %ARGS ) = validate( @_, {
        begin => { type => SCALAR },
        end => { type => SCALAR },
    } );
    my $holidays = holidays_in_daterange( %ARGS );
    my $res = {};
    my $d = $ARGS{begin};
    $log->debug( "holidays_and_weekends \$d == $d" );
    while ( $d ne get_tomorrow( $ARGS{end} ) ) {
        $res->{ $d } = {};
        if ( is_weekend( $d ) ) {
            $res->{ $d }->{ 'weekend' } = 1;
        }
        if ( exists( $holidays->{ $d } ) ) {
            $res->{ $d }->{ 'holiday' } = 1;
        }
        $d = get_tomorrow( $d );
    }
    return $res;
}


=head2 tsrange_to_dates_and_times

Takes a string that might be a canonicalized tsrange. Attempts to extract
beginning and ending dates (YYYY-MM-DD) from it. If this succeeds, an OK status
object is returned, the payload of which is a hash suitable for passing to
holidays_and_weekends().

=cut

sub tsrange_to_dates_and_times {
    my ( $tsrange ) = @_;

    my ( $begin_date, $begin_time, $end_date, $end_time ) = 
        $tsrange =~ m/(\d{4}-\d{2}-\d{2}).+(\d{2}:\d{2}):\d{2}.+(\d{4}-\d{2}-\d{2}).+(\d{2}:\d{2}):\d{2}/;

    # if begin_time is 24:00 convert it to 00:00
    if ( $begin_time eq '24:00' ) {
        my ( $y, $m, $d ) = canon_to_ymd( $begin_date );
        $log->debug( "Before Add_Delta_Days $y $m $d" );
        ( $y, $m, $d ) = Add_Delta_Days( $y, $m, $d, 1 );
        $begin_date = ymd_to_canon( $y, $m, $d );
    }



( run in 0.352 second using v1.01-cache-2.11-cpan-e1769b4cff6 )