The weekly challenge 259 - Task 1: Banking Day Offset
1 #!/usr/bin/env perl
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 use strict;
43 use warnings;
44 use Date::Calc qw(Day_of_Week Add_Delta_Days);
45
46 banking_day_offset('2018-06-28', 3, ['2018-07-03']);
47 banking_day_offset('2018-06-28', 3);
48
49 sub banking_day_offset {
50 my ($start_date, $offset, $bank_holidays) = @_;
51 $bank_holidays //= [];
52 print "Input: start_date = $start_date, offset = $offset, bank_holidays = [" . join(", ", @$bank_holidays) . "]\n";
53 while($offset > 0) {
54 my $next_date = next_day($start_date);
55 if( is_bankholiday_or_weekend($next_date, $bank_holidays) ) {
56 $start_date = $next_date;
57 next;
58 }
59 $offset--;
60 $start_date = $next_date;
61 }
62 print "Output: $start_date\n";
63 }
64
65 sub is_bankholiday_or_weekend {
66 my ($date, $bank_holidays) = @_;
67 return 1 if Day_of_Week(split(/-/, $date)) > 5;
68 foreach my $d (@$bank_holidays) {
69 return 1 if $d eq $date;
70 }
71 return 0;
72 }
73
74 sub next_day {
75 my $date = shift;
76 my ($year, $month, $day) = split /-/, $date;
77 my @new_date = Add_Delta_Days($year, $month, $day, 1);
78 my $d = sprintf("%04d-%02d-%02d", @new_date);
79 return $d;
80 }