Skip to content

Commit

Permalink
fix: alarm rings at wrong time on summer/winter time change
Browse files Browse the repository at this point in the history
  • Loading branch information
Bnyro committed Sep 21, 2024
1 parent ff63706 commit a99972f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
16 changes: 16 additions & 0 deletions app/src/main/java/com/bnyro/clock/util/AlarmHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import java.util.GregorianCalendar

object AlarmHelper {
const val EXTRA_ID = "alarm_id"
private const val HOUR_IN_MILLIS = 60 * 60 * 1000

@SuppressLint("ScheduleExactAlarm")
fun enqueue(context: Context, alarm: Alarm) {
Expand Down Expand Up @@ -79,9 +80,24 @@ object AlarmHelper {
calendar.add(Calendar.MILLISECOND, alarm.time.toInt())

calendar.add(Calendar.DATE, getPostponeDays(alarm, calendar))

fixDaylightTime(calendar)

return calendar.timeInMillis
}

fun fixDaylightTime(calendar: GregorianCalendar) {
val now = TimeHelper.currentTime

if (calendar.timeZone.useDaylightTime()) {
if (calendar.timeZone.inDaylightTime(now) && !calendar.timeZone.inDaylightTime(calendar.time)) {
calendar.timeInMillis += HOUR_IN_MILLIS
} else if (!calendar.timeZone.inDaylightTime(now) && calendar.timeZone.inDaylightTime(calendar.time)) {
calendar.timeInMillis -= HOUR_IN_MILLIS
}
}
}

private fun getPostponeDays(alarm: Alarm, calendar: GregorianCalendar): Int {
if (alarm.days.isEmpty() && alarm.repeat) return 0

Expand Down
37 changes: 37 additions & 0 deletions app/src/test/java/com/bnyro/clock/SummerTimeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.bnyro.clock

import com.bnyro.clock.util.AlarmHelper
import org.junit.Test
import java.util.Date
import java.util.GregorianCalendar
import java.util.TimeZone

class SummerTimeTest {
@Test
fun scheduleWithSummerTime() {
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"))
val date = Date(Date.UTC(2024, 10, 30, 15, 0, 0))
val calendar = GregorianCalendar()
calendar.time = date
val millis = calendar.timeInMillis
AlarmHelper.fixDaylightTime(calendar)

if (calendar.timeZone.inDaylightTime(calendar.time)) {
assert(millis == calendar.timeInMillis + 60 * 60 * 1000L)
} else {
assert(millis == calendar.timeInMillis - 60 * 60 * 1000L)
}
}

@Test
fun scheduleWithoutDaylightDiff() {
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"))
val date = Date()
val calendar = GregorianCalendar()
calendar.time = date
val millis = calendar.timeInMillis
AlarmHelper.fixDaylightTime(calendar)

assert(millis == calendar.timeInMillis)
}
}

0 comments on commit a99972f

Please sign in to comment.