Skip to content

Commit

Permalink
Fix calculation of events repeating every X weeks
Browse files Browse the repository at this point in the history
The previous implementation was broken on some time zones (see FossifyOrg#408
for details).

The new implementation hard-codes the start of the week to be Monday
to match the previous behaviour. Ideally this should be configurable
(see the TODO comment for more notes).

Fixes FossifyOrg#408.
  • Loading branch information
tom93 committed Jan 4, 2025
1 parent c65ae97 commit 27fcc6a
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions app/src/main/kotlin/org/fossify/calendar/models/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import org.fossify.calendar.extensions.seconds
import org.fossify.calendar.helpers.*
import org.fossify.commons.extensions.addBitIf
import org.joda.time.DateTime
import org.joda.time.DateTimeConstants
import org.joda.time.DateTimeZone
import org.joda.time.Weeks
import java.io.Serializable

@Entity(tableName = "events", indices = [(Index(value = ["id"], unique = true))])
Expand Down Expand Up @@ -176,11 +178,18 @@ data class Event(
fun getCalDAVCalendarId() = if (source.startsWith(CALDAV)) (source.split("-").lastOrNull() ?: "0").toString().toInt() else 0

// check if it's the proper week, for events repeating every x weeks
// get the week number since 1970, not just in the current year
fun isOnProperWeek(startTimes: LongSparseArray<Long>): Boolean {
val initialWeekNumber = Formatter.getDateTimeFromTS(startTimes[id!!]!!).withTimeAtStartOfDay().millis / (7 * 24 * 60 * 60 * 1000f)
val currentWeekNumber = Formatter.getDateTimeFromTS(startTS).withTimeAtStartOfDay().millis / (7 * 24 * 60 * 60 * 1000f)
return (Math.round(initialWeekNumber) - Math.round(currentWeekNumber)) % (repeatInterval / WEEK) == 0
// TODO: The start of the week is currently hard-coded to be Monday. It should be configurable.
// For reference, Google Calendar uses the value of the "Start of the week" setting at the time the event is created/edited.
// (The start of the week is significant for events that repeat on multiple days of the week.)
if (repeatInterval == WEEK) {
return true // optimization for events that repeat every week
}
val initialDate = Formatter.getDateFromTS(startTimes[id!!]!!)
val initialWeekStart = initialDate.minusDays((initialDate.getDayOfWeek() - DateTimeConstants.MONDAY + 7) % 7)
val currentDate = Formatter.getDateFromTS(startTS)
val weeks = Weeks.weeksBetween(initialDate, currentDate).weeks
return weeks % (repeatInterval / WEEK) == 0
}

fun updateIsPastEvent() {
Expand Down

0 comments on commit 27fcc6a

Please sign in to comment.