Use kotlinx.datetime.Timezone instead of java ZoneId

Change-Id: I62c4d044b319a9b59e06bb42fd12971d992e8628
pull/1187/head
Tomáš Mlynarič 11 months ago
parent a16d5f726c
commit ea1573fcc1

@ -39,9 +39,9 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.TimeZone
import org.junit.Rule
import org.junit.Test
import java.time.ZoneId
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@ -199,7 +199,7 @@ class NiaAppStateTest {
timeZoneMonitor = timeZoneMonitor,
)
}
val changedTz = ZoneId.of("Europe/Prague")
val changedTz = TimeZone.of("Europe/Prague")
backgroundScope.launch { state.currentTimeZone.collect() }
timeZoneMonitor.setTimeZone(changedTz)
assertEquals(

@ -47,7 +47,7 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand
import com.google.samples.apps.nowinandroid.core.ui.LocalZoneId
import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone
import com.google.samples.apps.nowinandroid.ui.NiaApp
import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState
import dagger.hilt.android.AndroidEntryPoint
@ -144,7 +144,7 @@ class MainActivity : ComponentActivity() {
CompositionLocalProvider(
LocalAnalyticsHelper provides analyticsHelper,
LocalZoneId provides currentZoneId,
LocalTimeZone provides currentZoneId,
) {
NiaTheme(
darkTheme = darkTheme,

@ -51,7 +51,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import java.time.ZoneId
import kotlinx.datetime.TimeZone
@Composable
fun rememberNiaAppState(
@ -140,11 +140,11 @@ class NiaAppState(
initialValue = emptySet(),
)
val currentTimeZone = timeZoneMonitor.currentZoneId
val currentTimeZone = timeZoneMonitor.currentTimeZone
.stateIn(
coroutineScope,
SharingStarted.WhileSubscribed(5_000),
ZoneId.systemDefault(),
TimeZone.currentSystemDefault(),
)
/**

@ -19,9 +19,9 @@ package com.google.samples.apps.nowinandroid.core.data.test
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import java.time.ZoneId
import kotlinx.datetime.TimeZone
import javax.inject.Inject
class DefaultZoneIdTimeZoneMonitor @Inject constructor() : TimeZoneMonitor {
override val currentZoneId: Flow<ZoneId> = flowOf(ZoneId.of("Europe/Warsaw"))
override val currentTimeZone: Flow<TimeZone> = flowOf(TimeZone.of("Europe/Warsaw"))
}

@ -34,10 +34,11 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.shareIn
import kotlinx.datetime.TimeZone
import java.time.ZoneId
import java.util.TimeZone
import javax.inject.Inject
import javax.inject.Singleton
@ -46,7 +47,7 @@ import javax.inject.Singleton
* It always emits at least once with default setting and then for each TZ change.
*/
interface TimeZoneMonitor {
val currentZoneId: Flow<ZoneId>
val currentTimeZone: Flow<TimeZone>
}
@Singleton
@ -56,10 +57,10 @@ internal class TimeZoneBroadcastMonitor @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
) : TimeZoneMonitor {
override val currentZoneId: SharedFlow<ZoneId> =
callbackFlow<ZoneId> {
override val currentTimeZone: SharedFlow<TimeZone> =
callbackFlow<TimeZone> {
// Send the default time zone first.
trySend(ZoneId.systemDefault())
trySend(TimeZone.currentSystemDefault())
// Registers BroadcastReceiver for the TimeZone changes
val receiver = object : BroadcastReceiver() {
@ -70,15 +71,15 @@ internal class TimeZoneBroadcastMonitor @Inject constructor(
null
} else {
// Starting Android R we also get the new TimeZone.
intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { zoneId ->
intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId ->
// We need to convert it from java.util.Timezone to java.time.ZoneId
ZoneId.of(zoneId, ZoneId.SHORT_IDS)
TimeZone.getTimeZone(zoneId).toZoneId()
val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS)
TimeZone.of(zoneId.id)
}
}
// If there isn't a zoneId in the intent, fallback to the systemDefault, which should also reflect the change
trySend(zoneIdFromIntent ?: ZoneId.systemDefault())
trySend(zoneIdFromIntent ?: TimeZone.currentSystemDefault())
}
}

@ -19,22 +19,22 @@ package com.google.samples.apps.nowinandroid.core.testing.util
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import java.time.ZoneId
import kotlinx.datetime.TimeZone
class TestTimeZoneMonitor : TimeZoneMonitor {
private val timeZoneFlow = MutableStateFlow(defaultTimeZone)
override val currentZoneId: Flow<ZoneId> = timeZoneFlow
override val currentTimeZone: Flow<TimeZone> = timeZoneFlow
/**
* A test-only API to set the from tests.
*/
fun setTimeZone(zoneId: ZoneId) {
fun setTimeZone(zoneId: TimeZone) {
timeZoneFlow.value = zoneId
}
companion object {
val defaultTimeZone: ZoneId = ZoneId.of("Europe/Warsaw")
val defaultTimeZone: TimeZone = TimeZone.of("Europe/Warsaw")
}
}

@ -17,10 +17,10 @@
package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.runtime.compositionLocalOf
import java.time.ZoneId
import kotlinx.datetime.TimeZone
/**
* ZoneId that can be provided with the TimeZoneMonitor.
* TimeZone that can be provided with the TimeZoneMonitor.
* This way, it's not needed to pass every single composable the time zone to show in UI.
*/
val LocalZoneId = compositionLocalOf { ZoneId.systemDefault() }
val LocalTimeZone = compositionLocalOf { TimeZone.currentSystemDefault() }

@ -69,6 +69,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import kotlinx.datetime.Instant
import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toJavaZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Locale
@ -244,7 +245,7 @@ fun NotificationDot(
fun dateFormatted(publishDate: Instant): String = DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.getDefault())
.withZone(LocalZoneId.current)
.withZone(LocalTimeZone.current.toJavaZoneId())
.format(publishDate.toJavaInstant())
@Composable

Loading…
Cancel
Save