Bump the changelog for the 0.7.5 release
[email-reminder.git] / EmailReminder / YearlyEvent.pm
blob4a2c7dba634287169f9c0eaaca64a6ae22ae3510
1 # This file is part of Email-Reminder.
3 # Email-Reminder is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License as
5 # published by the Free Software Foundation; either version 3 of the
6 # License, or (at your option) any later version.
8 # Email-Reminder is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with Email-Reminder; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 # 02110-1301, USA.
18 package EmailReminder::YearlyEvent;
20 use strict;
21 use warnings;
22 use overload '""' => \&str;
23 use Date::Manip;
24 use POSIX;
26 use EmailReminder::Utils;
28 use base qw(EmailReminder::Event);
30 # XML tags
31 __PACKAGE__->mk_accessors(qw(day month year));
33 # Global date variables
34 my $current_time = ParseDate("now");
35 my $current_date = ParseDate(UnixDate($current_time, "\%x"));
36 my $current_year = UnixDate($current_time, "\%Y");
37 my $leap_year = "1980";
39 sub str {
40 my ($self) = @_;
41 return $self->get_type . ':' . $self->get_id . ') ' . $self->get_name . ' - ' . $self->get_date;
44 # Hard-coded value for this event's type (class method)
45 sub get_type
47 return 'yearly';
50 # Number of fields this event adds to its parent (class method)
51 sub get_nb_fields
53 my ($self) = @_;
54 return $self->SUPER::get_nb_fields() + 2;
57 sub valid_day
59 my ($class, $new_value) = @_;
61 return 1 unless defined $new_value;
62 $new_value = int($new_value);
63 return $new_value if ($new_value >= 1 and $new_value <= 31);
64 return 1;
67 sub valid_month
69 my ($class, $new_value) = @_;
71 return 1 unless defined $new_value;
72 $new_value = int($new_value);
73 return $new_value if ($new_value >= 1 and $new_value <= 12);
74 return 1;
77 sub valid_year
79 my ($class, $new_value) = @_;
80 return 0 unless defined $new_value;
81 return int($new_value);
84 sub get_date
86 my ($self) = @_;
88 my $day = $self->get_day;
89 my $month = $self->get_month;
90 my $year = $self->get_year;
92 # Hack to support events that don't have a starting year
93 my $actual_date;
94 if (defined($year)) {
95 $self->{"MISSING_YEAR"} = 0;
96 $actual_date = UnixDate(ParseDate($year ."-".$month."-".$day),
97 "\%Y-\%m-\%d");
99 elsif (defined($month) && defined($day)) {
100 $self->{"MISSING_YEAR"} = 1;
101 my $full_date = UnixDate(ParseDate($leap_year."-".$month."-".$day),
102 "\%Y-\%m-\%d");
103 $actual_date = UnixDate(ParseDate($full_date), "\%m-\%d");
106 return $actual_date;
109 sub set_date
111 my ($self, $new_value) = @_;
112 my $date;
114 # Normalize the date entered by the user
115 my @slash_parts = split(/\//, $new_value);
116 my @dash_parts = split(/-/, $new_value);
117 if (@slash_parts == 2) {
118 $date = $new_value;
119 if ($slash_parts[0] <= 12) {
120 # Looks like a MM/DD date, don't parse further
121 $date =~ s/(.*)\/(.*)/$1-$2/g;
122 } else {
123 # Looks like a DD/MM date, don't parse further
124 $date =~ s/(.*)\/(.*)/$2-$1/g;
127 elsif (@dash_parts == 2) {
128 $date = $new_value;
129 if ($dash_parts[0] > 12) {
130 # Looks like a DD-MM date, don't parse further
131 $date =~ s/(.*)-(.*)/$2-$1/g;
134 else {
135 # Try to parse the date in whatever form the user typed it
136 $date = UnixDate(ParseDate($new_value), "\%Y-\%m-\%d");
139 if (defined($date)) {
140 my @parts = split /-/, $date;
141 my $day = pop(@parts);
142 my $month = pop(@parts);
143 my $year = undef;
144 $year = pop(@parts) if @parts;
146 return ($self->set_day($day) and $self->set_month($month) and $self->set_year($year));
147 } else {
148 return 0;
152 sub get_original_date
154 my ($self) = @_;
155 my $date_string = $self->get_date();
156 return unless $date_string;
158 $date_string = $leap_year."-".$date_string if $self->{"MISSING_YEAR"};
159 return ParseDate($date_string);
162 sub get_subject
164 my $self = shift;
165 return $self->get_name();
168 sub get_message_body
170 my $self = shift;
172 # event details
173 my $when = $self->{"WHEN"};
174 my $name = $self->get_name();
175 my $occurence = $self->get_occurence();
176 my $th = EmailReminder::Utils::get_th($occurence);
177 my $event = defined($occurence) ? "${occurence}$th $name" : $name;
179 my $message = <<"MESSAGEEND";
180 I just want to remind you of the following event $when:
182 $event
183 MESSAGEEND
185 return $message;
188 # Returns the occurence number of this event (starts at 1)
189 sub get_occurence
191 my $self = shift;
193 my $exact_age;
194 unless ($self->{"MISSING_YEAR"}) {
195 my $original_date = $self->get_original_date();
196 return unless $original_date;
198 my $delta = DateCalc($original_date, $current_date, 1);
199 $exact_age = Delta_Format($delta, 5, '%yd') + 1;
202 return defined($exact_age) ? ceil($exact_age) : undef;
205 # Returns 1 if the event will occur in X days (X is a param)
206 sub will_occur
208 my $self = shift;
209 my $modifier = shift;
211 # Apply the modifier to the event date
212 my $modified_date = $self->get_original_date();
213 return 0 unless $modified_date;
215 if ($modifier) {
216 $modified_date = DateCalc($modified_date, " - $modifier days");
218 return 0 unless $modified_date;
220 my $current_occurence_date = ParseDate(UnixDate($modified_date, "$current_year-\%m-\%d"));
221 if (Date_Cmp($current_date, $current_occurence_date) == 0) {
222 return 1;
223 } else {
224 # If an event is scheduled on Feb. 29th, remind on the 28th
225 if (UnixDate($modified_date, "\%m-\%d") eq "02-29" and
226 UnixDate($current_date, "\%m-\%d") eq "02-28") {
227 return 1;
228 } else {
229 return 0;