From 02cb1aba4628cd43c3732bf648c761a1df7f484d Mon Sep 17 00:00:00 2001 From: Marco Gomiero Date: Sun, 1 Oct 2023 00:11:10 +0100 Subject: [PATCH] Fix timezone issues --- gradle/libs.versions.toml | 4 -- shared/build.gradle.kts | 3 +- .../domain/JvmAndroidDateFormatter.kt | 41 ++++++++++++++----- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8f14425f..13868400 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,11 +27,9 @@ versions-ben-manes = "0.44.0" viewModel-ktx = "2.6.1" viewModel-compose = "2.6.1" lifecycle-runtime-compose = "2.6.1" -kotlinx-serialization = "1.5.1" org-robolectric = "4.9" sql-delight = "2.0.0" rss-parser = "6.0.2" -kotlinx-date-time = "0.4.0" accompanist = "0.28.0" jsoup = "1.15.3" triplet-play = "3.8.1" @@ -77,7 +75,6 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } -kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } slf4j-nop = { module = "org.slf4j:slf4j-nop", version.ref = "slf4jNop" } touchlab-kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } touchlab-kermit-simple = { module = "co.touchlab:kermit-simple", version.ref = "kermit" } @@ -91,7 +88,6 @@ sqldelight-runtime = { module = "app.cash.sqldelight:runtime", version.ref = "sq sqldelight-sqlite-driver = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sql-delight" } sqldelight-primitive-adapter = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sql-delight" } com-prof18-rss-parser = { module = "com.prof18.rssparser:rssparser", version.ref = "rss-parser" } -kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-date-time" } accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" } jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } decompose = { module = "com.arkivanov.decompose:decompose", version.ref = "decompose" } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index bbbbd766..41df846d 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -71,8 +71,6 @@ kotlin { implementation(libs.kotlinx.coroutines.core) implementation(libs.com.prof18.rss.parser) implementation(libs.multiplatform.settings) - implementation(libs.kotlin.test) - implementation(libs.kotlin.test.junit) api(project(":core")) api(project(":i18n")) @@ -82,6 +80,7 @@ kotlin { val commonTest by getting { dependencies { implementation(kotlin("test")) + implementation(libs.kotlin.test.junit) implementation(libs.kotlinx.coroutines.test) implementation(libs.touchlab.kermit.test) } diff --git a/shared/src/commonJvmAndroidMain/kotlin/com/prof18/feedflow/domain/JvmAndroidDateFormatter.kt b/shared/src/commonJvmAndroidMain/kotlin/com/prof18/feedflow/domain/JvmAndroidDateFormatter.kt index 73ec7242..c012c471 100644 --- a/shared/src/commonJvmAndroidMain/kotlin/com/prof18/feedflow/domain/JvmAndroidDateFormatter.kt +++ b/shared/src/commonJvmAndroidMain/kotlin/com/prof18/feedflow/domain/JvmAndroidDateFormatter.kt @@ -1,11 +1,14 @@ package com.prof18.feedflow.domain import co.touchlab.kermit.Logger +import java.time.DateTimeException import java.time.Instant import java.time.LocalDateTime import java.time.ZoneId +import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatterBuilder +import java.util.Locale internal class JvmAndroidDateFormatter( private val logger: Logger, @@ -28,12 +31,26 @@ internal class JvmAndroidDateFormatter( "[dd MMM yyyy HH:mm:ss Z]", ), ) - val dateTimeFormatter = dateTimeFormatterBuilder.toFormatter() + + val dateTimeFormatter = dateTimeFormatterBuilder.toFormatter(Locale.ENGLISH) + return try { - LocalDateTime.parse(dateString, dateTimeFormatter) + val temporalAccessor = dateTimeFormatter.parse(dateString) DateParsingResult.Parsed( - date = LocalDateTime.parse(dateString, dateTimeFormatter), + date = ZonedDateTime.from(temporalAccessor).withZoneSameInstant(ZoneId.systemDefault()), ) + } catch (e: DateTimeException) { + try { + val localDateTime = LocalDateTime.parse(dateString, dateTimeFormatter) + DateParsingResult.Parsed( + date = localDateTime.atZone(ZoneId.systemDefault()), + ) + } catch (e: Throwable) { + DateParsingResult.ParsingError( + exception = e, + message = "Error while trying to format the date with dateFormatter. Date: $dateString", + ) + } } catch (e: Throwable) { DateParsingResult.ParsingError( exception = e, @@ -46,7 +63,7 @@ internal class JvmAndroidDateFormatter( override fun getDateMillisFromString(dateString: String): Long? { val parseResult = parseDateString(dateString) return if (parseResult is DateParsingResult.Parsed) { - parseResult.date.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000 + parseResult.date.toEpochSecond() * 1000 } else { val exception = (parseResult as DateParsingResult.ParsingError).exception logger.e(exception) { @@ -58,17 +75,21 @@ internal class JvmAndroidDateFormatter( override fun formatDate(millis: Long): String { val instant = Instant.ofEpochMilli(millis) - val dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()) - val today = LocalDateTime.now(ZoneId.systemDefault()) - val isToday = dateTime.toLocalDate() == today.toLocalDate() + val userTimeZone = ZoneId.systemDefault() + val zonedDateTime = instant.atZone(userTimeZone) + val today = ZonedDateTime.now() + val isToday = zonedDateTime.toLocalDate() == today.toLocalDate() val pattern = if (isToday) { "HH:mm" } else { "dd/MM - HH:mm" } - val formatter = DateTimeFormatter.ofPattern(pattern) - return formatter.format(dateTime) + + val formatter = DateTimeFormatter + .ofPattern(pattern) + .withZone(zonedDateTime.zone) + return formatter.format(zonedDateTime) } override fun currentTimeMillis(): Long = @@ -76,7 +97,7 @@ internal class JvmAndroidDateFormatter( private sealed class DateParsingResult { data class Parsed( - val date: LocalDateTime, + val date: ZonedDateTime, ) : DateParsingResult() data class ParsingError(