我遇到了这样一个奇怪的情况:我使用DateTimeForMatter的函数对我来说工作得很好(即RSS提要列表按照它发布的顺序进行排序),但对于我的应用程序的一些用户来说,它崩溃了.起初,我以为可能有一个与地区相关的问题,但似乎所有的RSS提要都使用locale.English格式,所以现在我没有 idea 了.我也有用户在他们的设备上设置了美式英语(我使用英国英语)的崩溃报告.是我的代码有问题还是其他可能的原因?

我使用罗马解析器,pubDates的解析方式如下:Sat Aug 12 12:51:34 GMT+01:00 2023

    suspend fun sortDateTimeAndSaveLatestHeadline() {
    val dataStore = AppDataStore(getApplication())
    val listOfStringDates: MutableList<String> = mutableListOf()
    val listOfHeadlines: MutableList<String> = mutableListOf()
    val listOfFeedTitles: MutableList<String> = mutableListOf()

    newsFeed.value?.forEach { feed ->
        listOfStringDates.add(feed.feedItem.pubDate)
        listOfHeadlines.add(feed.feedItem.title)
        listOfFeedTitles.add(feed.feedTitle)
    }

    val zippedLists = listOfStringDates.zip(listOfHeadlines)
        .zip(listOfFeedTitles) { (a, b), c -> Triple(a, b, c) }

    val dateTimeFormatter: DateTimeFormatter =
        DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O yyyy",  Locale.ENGLISH)

    val result = zippedLists.sortedByDescending {
        LocalDateTime.parse(it.first, dateTimeFormatter)
    }

    if (result.isNotEmpty()) {
        dataStore.saveTileHeadline(result[0].second)
        dataStore.saveFeedTitle(result[0].third)
        println("Headline = ${result[0].second}")
    }
}

这是堆栈跟踪:

  Exception java.time.format.DateTimeParseException:
  at java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1949)
  at java.time.format.DateTimeFormatter.parse (DateTimeFormatter.java:1851)
  at java.time.LocalDateTime.parse (LocalDateTime.java:486)
  at java.util.TimSort.countRunAndMakeAscending (TimSort.java:355)
  at java.util.TimSort.sort (TimSort.java:220)
  at java.util.Arrays.sort (Arrays.java:1424)
  at kotlin.collections.CollectionsKt___CollectionsKt.sortedWith (CollectionsKt___Collections.kt)
  at com.strangerweather.news.presentation.screens.screens.FeedItemsScreenKt$FeedItemsScreen$7$1.invoke (FeedItemsScreen.kt)
  at androidx.wear.compose.foundation.lazy.ScalingLazyColumnKt$ScalingLazyColumn$1$1$2$1.invoke (ScalingLazyColumn.kt)
  at androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.<init> (LazyLayoutIntervalContent.java)
  at androidx.compose.foundation.lazy.LazyListIntervalContent.<init> (LazyListIntervalContent.java)
  at androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.java)
  at androidx.compose.runtime.DerivedSnapshotState.currentRecord (DerivedSnapshotState.java)
  at androidx.compose.runtime.snapshots.SnapshotKt.getLock (Snapshot.kt)
  at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.readableHash (DerivedSnapshotState.java)
  at androidx.compose.runtime.snapshots.SnapshotKt.getLock (Snapshot.kt)
  at androidx.compose.runtime.DerivedSnapshotState$ResultRecord.isValid (DerivedSnapshotState.java)
  at androidx.compose.runtime.DerivedSnapshotState.currentRecord (DerivedSnapshotState.java)
  at androidx.compose.runtime.DerivedSnapshotState.getCurrentRecord (DerivedSnapshotState.java)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.recordInvalidation (SnapshotStateObserver.java)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver.drainChanges (SnapshotStateObserver.java)
  at androidx.compose.runtime.snapshots.SnapshotStateObserver.access$drainChanges (SnapshotStateObserver.java)
  at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot (Snapshot.kt)
  at androidx.compose.runtime.snapshots.SnapshotKt.advanceGlobalSnapshot (Snapshot.kt)
  at androidx.compose.runtime.snapshots.SnapshotKt.access$advanceGlobalSnapshot (Snapshot.kt)
  at androidx.compose.runtime.snapshots.GlobalSnapshot.notifyObjectsInitialized$runtime_release (GlobalSnapshot.java)
  at androidx.compose.runtime.DerivedSnapshotState.currentRecord (DerivedSnapshotState.java)
  at androidx.compose.runtime.snapshots.Snapshot$Companion.getCurrent (Snapshot.java)
  at androidx.compose.runtime.DerivedSnapshotState.getValue (DerivedSnapshotState.java)
  at androidx.wear.compose.foundation.lazy.ScalingLazyListState.getLayoutInfo (ScalingLazyListState.java)
  at androidx.wear.compose.foundation.lazy.ScalingLazyListState.scrollToItem$compose_foundation_release (ScalingLazyListState.java)
  at androidx.wear.compose.foundation.lazy.ScalingLazyListState.scrollToInitialItem$compose_foundation_release (ScalingLazyListState.java)
  at androidx.wear.compose.foundation.lazy.ScalingLazyColumnKt$ScalingLazyColumn$1$1$3$1.invokeSuspend (ScalingLazyColumn.kt)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (BaseContinuationImpl.java)
  at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.java)
  at androidx.compose.ui.platform.AndroidUiDispatcher.nextTask (AndroidUiDispatcher.java)
  at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch (AndroidUiDispatcher.java)
  at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch (AndroidUiDispatcher.java)
  at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run (AndroidUiDispatcher.java)
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:246)
  at android.app.ActivityThread.main (ActivityThread.java:7690)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:593)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:995)

推荐答案

从您在代码和注释中提供的描述来看,您的应用程序似乎正在获取不同格式的时区信息,例如GMT+01:00、美国东部夏令时等.因此,您应该为时区使用多个可选模式.

Demo:

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss [O][z] uuuu", Locale.ENGLISH);

        // Test
        Stream.of(
                "Sat Aug 12 12:51:34 GMT+01:00 2023",
                "Fri Aug 18 12:34:50 EDT 2023"
        ).forEach(s -> System.out.println(ZonedDateTime.parse(s, dtf)));
    }
}

Output:

2023-08-12T12:51:34+01:00
2023-08-18T12:34:50-04:00[America/New_York]

Online Demo

Notes:

  1. 我在演示中只使用了两个可选模式.您可以根据需要进一步扩展,例如,"EEE MMM dd HH:mm:ss [O][z][VV] uuuu"有三个可选图案.
  2. 在这里,你可以用y代替u,而用I prefer u to y.

Kotlin相关问答推荐

如何在Kotlin中为接受varargs的函数添加带有默认值的新参数?

在Jetpack Compose中创建波浪式文本动画:顺序中断问题

为什么Kotlin协程程序即使有延迟也能输出?

如何让 LocalDateTime.parse 拒绝 24:00 时间

修改器的属性是什么,我需要更改以使角变圆且宽度更小?喷气背包组合

第二个协程永远不会执行

在 Compose 中使用 Text() 时如何获取文本的大小?

测试协程和线程之间的差异,我在kotlin中使用线程时无法得到OOM错误

为什么 Kotlin 的 null 安全性不能与局部变量初始化器一起正常工作?

Swift vs Kotlin 在排序数组上的表现

Android 在将 androidx 生物识别更新为 1.0.0-alpha04 后崩溃

Kotlin 中的部分类委托

如何从 Java 中隐藏 Kotlin 的 lateinit var 支持字段?

将 Android Studio 升级到 3.1.0 后的 Android Support 插件错误

如何在 Jetpack Compose 的 LazyColumn/LazyRow 中禁用和启用滚动?

Kotlin:相互递归函数的尾部递归

uses-sdk:minSdkVersion 16 不能小于库中声明的版本 23

如何根据ArrayList的对象属性值从中获取最小/最大值?

在 IntelliJ Idea 中未为 Kotlin @ConfigurationProperties 类生成 spring-configuration-metadata.json 文件

Android Compose 生产准备好了吗?