File Coverage

blib/lib/Acme/PM/Berlin/Meetings.pm
Criterion Covered Total %
statement 45 45 100.0
branch 15 16 93.7
condition 3 5 60.0
subroutine 8 8 100.0
pod 0 2 0.0
total 71 76 93.4


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # Author: Slaven Rezic
5             #
6             # Copyright (C) 2010,2012,2015,2016,2017 Slaven Rezic. All rights reserved.
7             # This package is free software; you can redistribute it and/or
8             # modify it under the same terms as Perl itself.
9             #
10             # Mail: slaven@rezic.de
11             # WWW: http://www.rezic.de/eserte/
12             #
13              
14             package Acme::PM::Berlin::Meetings;
15              
16 2     2   103445 use strict;
  2         4  
  2         122  
17             our $VERSION = '201703.19';
18              
19 2     2   10 use Exporter 'import'; # needs Exporter 5.57
  2         5  
  2         118  
20             our @EXPORT = qw(next_meeting);
21              
22 2     2   1858 use DateTime;
  2         788794  
  2         715  
23              
24             sub next_meeting {
25 1   50 1 0 86 my $count = shift || 1;
26 1         10 my $dt = DateTime->now(time_zone => 'local');
27 1         3745 map { $dt = next_meeting_dt($dt) } (1 .. $count);
  1         4  
28             }
29              
30             sub next_meeting_dt {
31 9     9 0 13579 my $dt = shift;
32 9         41 my $dt_berlin = $dt->clone->set_time_zone('Europe/Berlin');
33 9 100 66     15094 if ($dt_berlin->month == 1 && $dt_berlin->day < 10) {
34 2         40 my $dec_meeting = _get_dec_meeting($dt_berlin);
35 2 100       12 if ($dec_meeting > $dt_berlin) {
36 1         80 return $dec_meeting;
37             }
38             }
39 8         162 my $last_wed_of_month = _get_last_wed_of_month($dt_berlin);
40 8 100       42 if ($last_wed_of_month <= $dt_berlin) {
41 2         148 $dt_berlin->add(months => 1, end_of_month => 'limit');
42 2         2345 $last_wed_of_month = _get_last_wed_of_month($dt_berlin);
43             }
44 8 100       478 if ($last_wed_of_month->month == 12) {
45 2         21 return _get_dec_meeting($last_wed_of_month);
46             }
47 6         78 $last_wed_of_month;
48             }
49              
50             sub _get_last_wed_of_month {
51 10     10   18 my $dt_berlin = shift;
52 10         36 my $last_day_of_month = DateTime->last_day_of_month(year => $dt_berlin->year, month => $dt_berlin->month, time_zone => 'Europe/Berlin');
53 10         5518 my $dow = $last_day_of_month->day_of_week;
54 10 100       92 my $last_wed_of_month = $last_day_of_month->add(days => $dow < 3 ? -$dow-4 : -$dow+3);
55 10         6604 _adjust_hour($last_wed_of_month);
56 10         6287 $last_wed_of_month;
57             }
58              
59             sub _get_dec_meeting {
60 4     4   8 my $dt = shift;
61 4         15 $dt = $dt->clone;
62 4 100       49 if ($dt->month == 12) {
63 2         20 $dt->add(months => 1); # end_of_month does not matter
64             }
65 4         2575 $dt->set(day => 3);
66 4         2555 my $dow = $dt->day_of_week;
67 4 50       41 $dt->add(days => $dow < 4 ? -$dow+3 : -$dow+10);
68 4         5194 _adjust_hour($dt);
69 4         2571 $dt;
70             }
71              
72             sub _adjust_hour {
73 14     14   31 my $dt = shift;
74 14 100       40 if ($dt->year >= 2016) {
75 5         42 $dt->set(hour => 19);
76             } else {
77 9         81 $dt->set(hour => 20);
78             }
79             }
80              
81             1;
82              
83             __END__
84              
85             =head1 NAME
86              
87             Acme::PM::Berlin::Meetings - get the next date of the Berlin PM meeting
88              
89             =head1 SYNOPSIS
90              
91             use Acme::PM::Berlin::Meetings;
92             next_meeting(1)
93              
94             Or use the bundled script:
95              
96             berlin-pm
97              
98             =head1 NOTES
99              
100             This module knows about special Berlin.PM traditions like postponing
101             the December meeting to the first or second week in January.
102              
103             =head1 AUTHOR
104              
105             Slaven Rezic
106              
107             =head1 SEE ALSO
108              
109             L<Acme::PM::Barcelona::Meeting>, L<Acme::PM::Paris::Meetings>.
110              
111             =cut