Skip to content

Instantly share code, notes, and snippets.

@AdnanHabibMirza
Last active June 20, 2025 18:20
Show Gist options
  • Select an option

  • Save AdnanHabibMirza/9ec6b6cc63f74b05f43ee8e4899a8a80 to your computer and use it in GitHub Desktop.

Select an option

Save AdnanHabibMirza/9ec6b6cc63f74b05f43ee8e4899a8a80 to your computer and use it in GitHub Desktop.
Utility for reporting current timezone the android device has set. It always emits at least once with default setting and then for each TZ change.
interface TimeZoneMonitor {
val currentTimeZone: Flow<TimeZone>
}
@Singleton
class TimeZoneBroadcastMonitor @Inject constructor(
@ApplicationContext private val context: Context,
@ApplicationScope appScope: CoroutineScope,
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
) : TimeZoneMonitor {
override val currentTimeZone: SharedFlow<TimeZone> = callbackFlow {
trySend(TimeZone.currentSystemDefault())
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_TIMEZONE_CHANGED) return
val zoneIdFromIntent = if (VERSION.SDK_INT < VERSION_CODES.R) {
null
} else {
intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId ->
val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS)
zoneId.toKotlinTimeZone()
}
}
trySend(zoneIdFromIntent ?: TimeZone.currentSystemDefault())
}
}
context.registerReceiver(receiver, IntentFilter(Intent.ACTION_TIMEZONE_CHANGED))
trySend(TimeZone.currentSystemDefault())
awaitClose {
context.unregisterReceiver(receiver)
}
}
.distinctUntilChanged()
.conflate()
.flowOn(ioDispatcher)
.shareIn(appScope, SharingStarted.WhileSubscribed(5_000), 1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment