diff options
author | Marius Halden <marius.h@lden.org> | 2021-10-07 13:32:40 +0200 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2021-10-07 13:32:40 +0200 |
commit | 09dacfc6b8bf62addeee16c20b1d90c2a256da96 (patch) | |
tree | 7caa2bf9e92227ab74448f9b746dd28bbcb81b2a /perllib/FixMyStreet/WorkingDays.pm | |
parent | 585e57484f9c6332668bf1ac0a6a3b39dbe32223 (diff) | |
parent | cea89fb87a96943708a1db0f646492fbfaaf000f (diff) |
Merge tag 'v3.1' into fiksgatami-devfiksgatami-dev
Diffstat (limited to 'perllib/FixMyStreet/WorkingDays.pm')
-rw-r--r-- | perllib/FixMyStreet/WorkingDays.pm | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/WorkingDays.pm b/perllib/FixMyStreet/WorkingDays.pm new file mode 100644 index 000000000..615b226c6 --- /dev/null +++ b/perllib/FixMyStreet/WorkingDays.pm @@ -0,0 +1,78 @@ +package FixMyStreet::WorkingDays; + +use Moo; + +=head1 FixMyStreet::WorkingDays + +Given a list of public holiday dates, creates an object that can be used to +add/subtract days from a date, only counting working days (excluding public +holidays and weekends). + +=over + +=cut + +has public_holidays => ( + is => 'ro', + coerce => sub { + return { map { $_ => 1 } @{$_[0]} }; + }, +); + +=item add_days + +Given a DateTime object and a number of days, returns a new DateTime object +that many working days (excluding public holidays and weekends) later. + +=cut + +sub add_days { + my ( $self, $dt, $days, $subtract ) = @_; + $dt = $dt->clone; + while ( $days > 0 ) { + $dt->add ( days => $subtract ? -1 : 1 ); + next if $self->is_public_holiday($dt); + next if $self->is_weekend($dt); + $days--; + } + return $dt; +} + +=item sub_days + +Given a DateTime object and a number of days, returns a new DateTime object +that many working days (excluding public holidays and weekends) earlier. + +=cut + +sub sub_days { + my $self = shift; + return $self->add_days(@_, 1); +} + +=item is_public_holiday + +Given a DateTime object, return true if it is a public holiday. + +=cut + +sub is_public_holiday { + my ($self, $dt) = @_; + return $self->public_holidays->{$dt->ymd}; +} + +=item is_weekend + +Given a DateTime object, return true if it is a weekend. + +=cut + +sub is_weekend { + my ($self, $dt) = @_; + return $dt->dow > 5; +} + +1; + +=back + |