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 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..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) { @@ -82,7 +84,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 +113,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 == DateTimeConstants.FEBRUARY && originalDay == LEAP_DAY) { + if (newDateTime.year().isLeap) { + //show on 29th Feb. (leap year) + newDateTime = newDateTime.withMonthOfYear(DateTimeConstants.FEBRUARY).withDayOfMonth(LEAP_DAY) + } else { + // show on March 1st (non-leap year) + newDateTime = newDateTime.withMonthOfYear(DateTimeConstants.MARCH).withDayOfMonth(FIRST_DAY) + } + } 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 }