Skip to content

Commit

Permalink
Display leap day anniversaries every year on calendars
Browse files Browse the repository at this point in the history
Added a new anniversary method to dates which returns a day and
month on which to display leap day anniversaries on non-leap
years.

Added an option in the preferences display tab which allows the
user to specify on which day the anniversary should be displayed.
The options are: 28th Feb, 1st Mar or only on 29th Feb.

Fixes #12511
  • Loading branch information
SNoiraud authored and Nick-Hall committed Jul 27, 2023
1 parent e2dbba4 commit f59e4d2
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 4 deletions.
1 change: 1 addition & 0 deletions gramps/gen/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ def emit(key):
register('preferences.date-format', 0)
register('preferences.calendar-format-report', 0)
register('preferences.calendar-format-input', 0)
register('preferences.february-29', 0) # 0: 02/28; 1: 03/01; 2: only the 02/29
register('preferences.cprefix', 'C%04d')
register('preferences.default-source', False)
register('preferences.tag-on-import', False)
Expand Down
19 changes: 19 additions & 0 deletions gramps/gen/lib/date.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#
# ------------------------------------------------------------------------
import logging
import calendar

# -------------------------------------------------------------------------
#
Expand Down Expand Up @@ -2064,6 +2065,24 @@ def make_vague(self):
self.dateval = tuple(dlist)
self._calc_sort_value()

def anniversary(self, year):
"""
If the date is February 29, you must choose the day to view it in the
event of a non-leap year.
This is usualy used in calendars.
"""
month = self.dateval[Date._POS_MON]
day = self.dateval[Date._POS_DAY]
if month == 2 and day == 29 and not calendar.isleap(year):
day_show = config.get('preferences.february-29')
if day_show == 0:
day = 28
elif day_show == 1:
month = 3
day = 1
# else: # In all other cases, keep the february 29 day
return (month, day)

year = property(get_year, set_year)


Expand Down
35 changes: 35 additions & 0 deletions gramps/gen/lib/test/date_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,41 @@ def test_span_empty(self):
d.set(value=(1, 1, 1900, False, 1, 1, 1910, False), modifier=Date.MOD_SPAN)
self.assertFalse(d.is_empty())

# -------------------------------------------------------------------------
#
# AnniversaryDateTest
#
# -------------------------------------------------------------------------
class AnniversaryDateTest(BaseDateTest):
"""
Tests for leap day anniversary dates.
"""

def test_leapyear_1(self):
config.set('preferences.february-29', 0)
d = Date(1904, 2, 29)
self.assertEqual(d.anniversary(1908), (2, 29))

def test_leapyear_2(self):
config.set('preferences.february-29', 1)
d = Date(1904, 2, 29)
self.assertEqual(d.anniversary(1908), (2, 29))

def test_nonleapyear_before(self):
config.set('preferences.february-29', 0)
d = Date(1904, 2, 29)
self.assertEqual(d.anniversary(1910), (2, 28))

def test_nonleapyear_after(self):
config.set('preferences.february-29', 1)
d = Date(1904, 2, 29)
self.assertEqual(d.anniversary(1910), (3, 1))

def test_nonleapyear_keep(self):
config.set('preferences.february-29', 2)
d = Date(1904, 2, 29)
self.assertEqual(d.anniversary(1910), (2, 29))


if __name__ == "__main__":
unittest.main()
23 changes: 23 additions & 0 deletions gramps/gui/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,23 @@ def add_data_panel(self, configdialog):
grid.attach(lwidget, 1, row, 1, 1)
grid.attach(obox, 2, row, 2, 1)

row += 1
# Birthday on february 29
feb29 = Gtk.ComboBoxText()
show_on = [_("on the previous day"),
_("on the next day"),
_("only on leap years")]
list(map(feb29.append_text, show_on))
active = config.get('preferences.february-29')
feb29.set_active(active)
feb29.connect('changed', self.date_february_29_display_on)
ttip = _("For non leap years, anniversaries are displayed on either "
"February 28, March 1 or not at all in Gregorian calendars")
feb29.set_tooltip_text(ttip)
lwidget = BasicLabel(_("Show leap day anniversaries"))
grid.attach(lwidget, 1, row, 1, 1)
grid.attach(feb29, 2, row, 2, 1)

row += 1
# Status bar:
obox = Gtk.ComboBoxText()
Expand Down Expand Up @@ -1572,6 +1589,12 @@ def date_calendar_for_input_changed(self, obj):
"""
config.set('preferences.calendar-format-input', obj.get_active())

def date_february_29_display_on(self, obj):
"""
Save "February 29 display on " option.
"""
config.set('preferences.february-29', obj.get_active())

def autobackup_changed(self, obj):
"""
Save "Autobackup" option on change.
Expand Down
2 changes: 2 additions & 0 deletions gramps/plugins/drawreport/calendarreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import datetime
import time
from functools import partial
import calendar

#------------------------------------------------------------------------
#
Expand Down Expand Up @@ -374,6 +375,7 @@ def get_surname_of_husband():
day = birth_date.get_day()

prob_alive_date = Date(self.year, month, day)
month, day = birth_date.anniversary(self.year)

nyears = self.year - year
short_name = self.get_name(
Expand Down
6 changes: 4 additions & 2 deletions gramps/plugins/textreport/birthdayreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#
#------------------------------------------------------------------------
import datetime, time
import calendar

#------------------------------------------------------------------------
#
Expand All @@ -37,8 +38,9 @@
_ = glocale.translation.gettext
from gramps.gen.const import URL_HOMEPAGE
from gramps.gen.errors import ReportError
from gramps.gen.config import config
from gramps.gen.lib import NameType, EventType, Name, Date, Person, Surname
from gramps.gen.lib.date import gregorian
from gramps.gen.lib.date import gregorian, Today
from gramps.gen.relationship import get_relationship_calculator
from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle,
FONT_SERIF, PARA_ALIGN_RIGHT,
Expand Down Expand Up @@ -291,7 +293,7 @@ def collect_data(self):
day = birth_date.get_day()

prob_alive_date = Date(self.year, month, day)

month, day = birth_date.anniversary(self.year)
nyears = self.year - year
# add some things to handle maiden name:
father_lastname = None # husband, actually
Expand Down
3 changes: 2 additions & 1 deletion gramps/plugins/webreport/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ def collect_data(self, this_year):
# current year of calendar, month nd day is their birth
# month and birth day
prob_alive_date = Date(this_year, month, day)

month, day = birth_date.anniversary(this_year)
# add some things to handle maiden name:
father_surname = None # husband, actually
if person.gender == Person.FEMALE:
Expand Down Expand Up @@ -1093,6 +1093,7 @@ def collect_data(self, this_year):
month = event_date.get_month()
day = event_date.get_day()

month, day = event_date.anniversary(this_year)
# date to figure if someone is still alive
prob_alive_date = Date(this_year,
month, day)
Expand Down
2 changes: 1 addition & 1 deletion gramps/plugins/webreport/webcal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1370,7 +1370,7 @@ def collect_data(self, this_year):
# current year of calendar, month nd day is their birth
# month and birth day
prob_alive_date = Date(this_year, month, day)

month, day = birth_date.anniversary(this_year)
# add some things to handle maiden name:
father_surname = None # husband, actually
if person.gender == Person.FEMALE:
Expand Down

0 comments on commit f59e4d2

Please sign in to comment.