From 2af2795431b014b13acfd4533ed5116c0d8a05bb Mon Sep 17 00:00:00 2001 From: Serunthi Date: Sat, 9 May 2026 03:37:02 +0200 Subject: [PATCH 1/3] fix: display leap year birthdays on the day following non-leap year (#1087) --- .../org/fossify/calendar/models/Event.kt | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/calendar/models/Event.kt b/app/src/main/kotlin/org/fossify/calendar/models/Event.kt index 74312ff04..2241afac1 100644 --- a/app/src/main/kotlin/org/fossify/calendar/models/Event.kt +++ b/app/src/main/kotlin/org/fossify/calendar/models/Event.kt @@ -82,7 +82,8 @@ data class Event( repeatInterval % YEAR == 0 -> when (repeatRule) { REPEAT_ORDER_WEEKDAY -> addXthDayInterval(oldStart, original, false) REPEAT_ORDER_WEEKDAY_USE_LAST -> addXthDayInterval(oldStart, original, true) - else -> addYearsWithSameDay(oldStart) + else -> addYearsWithSameDay(oldStart, original) + } repeatInterval % MONTH == 0 -> when (repeatRule) { @@ -110,15 +111,27 @@ data class Event( } // if an event should happen on 29th Feb. with Same Day yearly repetition, show it only on leap years - private fun addYearsWithSameDay(currStart: DateTime): DateTime { + // show on March 1st in non-leap years + private fun addYearsWithSameDay(currStart: DateTime, original: Event): DateTime { + val originalDateTime = Formatter.getDateTimeFromTS(original.startTS) + val originalDay = originalDateTime.dayOfMonth + val originalMonth = originalDateTime.monthOfYear var newDateTime = currStart.plusYears(repeatInterval / YEAR) - // Date may slide within the same month - if (newDateTime.dayOfMonth != currStart.dayOfMonth) { - while (newDateTime.dayOfMonth().maximumValue < currStart.dayOfMonth) { + if (originalMonth == 2 && originalDay == 29) { + if (newDateTime.year().isLeap) { + //show on 29th Feb. (leap year) + newDateTime = newDateTime.withMonthOfYear(2).withDayOfMonth(29) + } else { + // show on March 1st (non-leap year) + newDateTime = newDateTime.withMonthOfYear(3).withDayOfMonth(1) + } + } else if (newDateTime.dayOfMonth != currStart.dayOfMonth) { + // Date may slide within the same month + while (newDateTime.dayOfMonth().maximumValue < originalDay) { newDateTime = newDateTime.plusYears(repeatInterval / YEAR) } - newDateTime = newDateTime.withDayOfMonth(currStart.dayOfMonth) + newDateTime = newDateTime.withDayOfMonth(originalDay) } return newDateTime } From e55374103be0c44a66e0d768e11f5e138126928c Mon Sep 17 00:00:00 2001 From: Serunthi Date: Sat, 9 May 2026 04:05:01 +0200 Subject: [PATCH 2/3] docs: update CHANGELOG for #1087 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73a6fc1f1..ea75dc716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed event text readability on colored backgrounds ([#1065]) - Fixed invisible current time indicator in weekly view ([#99]) - Fixed stuck zoom level in weekly view on some devices ([#621]) +- Fixed leap day birthdays not showing in non-leap years ([#1087]) ## [1.10.3] - 2026-02-14 ### Changed From cdb0ca09aabf40567b934fb71d9bb5eeccfd0a5d Mon Sep 17 00:00:00 2001 From: Serunthi Date: Sat, 9 May 2026 16:44:01 +0200 Subject: [PATCH 3/3] fix: replace magic numbers with constants --- app/src/main/kotlin/org/fossify/calendar/models/Event.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/calendar/models/Event.kt b/app/src/main/kotlin/org/fossify/calendar/models/Event.kt index 2241afac1..8fe51bc8e 100644 --- a/app/src/main/kotlin/org/fossify/calendar/models/Event.kt +++ b/app/src/main/kotlin/org/fossify/calendar/models/Event.kt @@ -71,6 +71,8 @@ data class Event( companion object { private const val serialVersionUID = -32456795132345616L + private const val LEAP_DAY = 29 + private const val FIRST_DAY = 1 } fun addIntervalTime(original: Event) { @@ -118,13 +120,13 @@ data class Event( val originalMonth = originalDateTime.monthOfYear var newDateTime = currStart.plusYears(repeatInterval / YEAR) - if (originalMonth == 2 && originalDay == 29) { + if (originalMonth == DateTimeConstants.FEBRUARY && originalDay == LEAP_DAY) { if (newDateTime.year().isLeap) { //show on 29th Feb. (leap year) - newDateTime = newDateTime.withMonthOfYear(2).withDayOfMonth(29) + newDateTime = newDateTime.withMonthOfYear(DateTimeConstants.FEBRUARY).withDayOfMonth(LEAP_DAY) } else { // show on March 1st (non-leap year) - newDateTime = newDateTime.withMonthOfYear(3).withDayOfMonth(1) + newDateTime = newDateTime.withMonthOfYear(DateTimeConstants.MARCH).withDayOfMonth(FIRST_DAY) } } else if (newDateTime.dayOfMonth != currStart.dayOfMonth) { // Date may slide within the same month