Skip to content

Commit

Permalink
[1.242.*] Pre-release merge (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
tramline-github[bot] authored Oct 2, 2024
2 parents 2a98cd8 + 2d44c04 commit 3411147
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,29 @@ import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoField
import java.time.temporal.UnsupportedTemporalTypeException
import java.util.Locale
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toJavaLocalDateTime
import kotlinx.datetime.toJavaZoneId
import kotlinx.datetime.toLocalDateTime

private val dateFormatters =
listOf(
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss O"),
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss Z"),
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss z"),
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm Z"),
DateTimeFormatter.ofPattern("E, d MMM yy HH:mm:ss Z"),
DateTimeFormatter.ofPattern("E, dd MMM yyyy"),
DateTimeFormatter.ofPattern("d MMM yyyy HH:mm:ss z"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssz"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z"),
DateTimeFormatter.ofPattern("yyyy-MM-dd"),
DateTimeFormatter.ofPattern("MM-dd HH:mm:ss"),
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss zzzz"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"),
)

@Throws(DateTimeFormatException::class)
actual fun String?.dateStringToEpochMillis(clock: Clock): Long? {
if (this.isNullOrBlank()) return null

val currentDate =
clock.now().toLocalDateTime(TimeZone.currentSystemDefault()).toJavaLocalDateTime()

for (dateFormatter in dateFormatters) {
for (pattern in dateFormatterPatterns) {
val dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, Locale.US)

try {
val parsedValue = parseToInstant(dateFormatter, this)
val parsedValue = parseToInstant(dateTimeFormatter, this)
return parsedValue.toEpochMilli()
} catch (e: Exception) {
try {
val parsedValue = fallbackParseToInstant(currentDate, dateFormatter, this)
val parsedValue = fallbackParseToInstant(currentDate, dateTimeFormatter, this)
return parsedValue.toEpochMilli()
} catch (e: Exception) {
// no-op
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,30 @@ package dev.sasikanth.rss.reader.util

import kotlinx.datetime.Clock

internal val dateFormatterPatterns =
setOf(
// Keep the two character year before parsing the four
// character year of similar pattern. Not sure why,
// but unlike JVM, iOS is not keep it strict?
"E, d MMM yy HH:mm:ss Z",
"E, d MMM yyyy HH:mm:ss O",
"E, d MMM yyyy HH:mm:ss Z",
"E, d MMM yyyy HH:mm:ss z",
"E, d MMM yyyy HH:mm Z",
"E, dd MMM yyyy",
"d MMM yyyy HH:mm:ss z",
"dd MMM yyyy HH:mm Z",
"yyyy-MM-dd'T'HH:mm:ssz",
"yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm:ss z",
"yyyy-MM-dd",
"MM-dd HH:mm:ss",
"E, d MMM yyyy HH:mm:ss zzzz",
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
)

expect fun String?.dateStringToEpochMillis(clock: Clock = Clock.System): Long?

data class DateTimeFormatException(val exception: Exception) : Exception()
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class DateTimeFormattersTest {
"Fri, 24 Nov 2023 23:13:00 GMT",
"Tue, 05 Dec 2023 15:55:50 PST",
"2023-12-12T11:20:18",
"2023-12-10T06:11:00.000-08:00"
"2023-12-10T06:11:00.000-08:00",
"01 Jun 2024 12:00 +0000",
"Thu, 26 Sep 2024 14:30:00 +0200",
)

val expectedEpochMillis =
Expand All @@ -65,7 +67,9 @@ class DateTimeFormattersTest {
1700867580000,
1701820550000,
1702380018000,
1702217460000
1702217460000,
1717243200000,
1727353800000
)

// when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,49 +33,26 @@ import platform.Foundation.NSDateFormatter
import platform.Foundation.NSLocale
import platform.Foundation.timeIntervalSince1970

private fun createDateFormatter(
pattern: String,
timeZone: TimeZone? = null,
): NSDateFormatter {
return NSDateFormatter().apply {
dateFormat = pattern
locale = NSLocale("en_US_POSIX")

timeZone?.let { this.timeZone = it.toNSTimeZone() }
}
}

private val dateFormatters =
listOf(
// Keep the two character year before parsing the four
// character year of similar pattern. Not sure why,
// but unlike JVM, iOS is not keep it strict?
createDateFormatter("E, d MMM yy HH:mm:ss Z"),
createDateFormatter("E, d MMM yyyy HH:mm:ss O"),
createDateFormatter("E, d MMM yyyy HH:mm:ss Z"),
createDateFormatter("E, d MMM yyyy HH:mm:ss z"),
createDateFormatter("E, d MMM yyyy HH:mm Z"),
createDateFormatter("E, dd MMM yyyy", TimeZone.UTC),
createDateFormatter("d MMM yyyy HH:mm:ss z"),
createDateFormatter("MM-dd HH:mm:ss", TimeZone.UTC),
createDateFormatter("yyyy-MM-dd'T'HH:mm:ssz"),
createDateFormatter("yyyy-MM-dd'T'HH:mm:ssZ"),
createDateFormatter("yyyy-MM-dd'T'HH:mm:ss", TimeZone.UTC),
createDateFormatter("yyyy-MM-dd HH:mm:ss", TimeZone.UTC),
createDateFormatter("yyyy-MM-dd HH:mm:ss z"),
createDateFormatter("yyyy-MM-dd", TimeZone.UTC),
createDateFormatter("E, d MMM yyyy HH:mm:ss zzzz"),
createDateFormatter("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"),
)

@Throws(DateTimeFormatException::class)
actual fun String?.dateStringToEpochMillis(clock: Clock): Long? {
if (this.isNullOrBlank()) return null

try {
val date =
dateFormatters.firstNotNullOfOrNull { dateFormatter ->
dateFormatter.dateFromString(this.trim())
dateFormatterPatterns.firstNotNullOfOrNull { pattern ->
val timeZone =
if (hasTimeZonePattern(pattern)) {
null
} else {
TimeZone.UTC
}
val dateTimeFormatter =
createDateFormatter(
pattern = pattern,
timeZone = timeZone,
)

dateTimeFormatter.dateFromString(this.trim())
}

if (date != null) {
Expand Down Expand Up @@ -114,3 +91,20 @@ actual fun String?.dateStringToEpochMillis(clock: Clock): Long? {

return null
}

private fun hasTimeZonePattern(pattern: String) =
pattern.contains("Z", ignoreCase = true) ||
pattern.contains("O", ignoreCase = true) ||
pattern.contains("X", ignoreCase = true)

private fun createDateFormatter(
pattern: String,
timeZone: TimeZone? = null,
): NSDateFormatter {
return NSDateFormatter().apply {
dateFormat = pattern
locale = NSLocale("en_US_POSIX")

timeZone?.let { this.timeZone = it.toNSTimeZone() }
}
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
kotlin = "2.0.20"
android_gradle_plugin = "8.6.1"
android_gradle_plugin = "8.7.0"
compose = "1.7.0-rc01"

android_sdk_compile = "34"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ import dev.sasikanth.rss.reader.util.DispatchersProvider
import dev.sasikanth.rss.reader.utils.NTuple4
import dev.sasikanth.rss.reader.utils.getLast24HourStart
import dev.sasikanth.rss.reader.utils.getTodayStartInstant
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.*
Expand Down Expand Up @@ -377,6 +379,7 @@ class HomePresenter(
.launchIn(coroutineScope)
}

@OptIn(FlowPreview::class)
private fun loadFeaturedPostsItems(
activeSource: Source?,
unreadOnly: Boolean?,
Expand All @@ -400,6 +403,7 @@ class HomePresenter(
)
}
}
.debounce(500.milliseconds)

private fun feedsSheetStateChanged(feedsSheetState: SheetValue) {
_state.update {
Expand Down

0 comments on commit 3411147

Please sign in to comment.