TzdbZoneRulesProvider 在 java.time 中不起作用

TzdbZoneRulesProvider not working in java.time

提问人:AndroidDev 提问时间:3/3/2023 最后编辑:SweeperAndroidDev 更新时间:3/3/2023 访问量:76

问:

我正在将旧的代码库从向后移植库中迁移出来以改用。有一种测试方法不再有效,但我不知道如何解决它。threetenjava.time

这是更改之前的类。这将正确编译:

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import org.junit.Before
import org.junit.Rule
import org.threeten.bp.ZoneId
import org.threeten.bp.zone.TzdbZoneRulesProvider
import org.threeten.bp.zone.ZoneRulesProvider

open class BaseAvailabilityTest {

    @get:Rule
    val rule = InstantTaskExecutorRule()

    @Before
    open fun setUp() {
        if (ZoneRulesProvider.getAvailableZoneIds().isEmpty()) {
            val stream = this.javaClass.classLoader?.getResourceAsStream("TZDB.dat")
            stream.use(::TzdbZoneRulesProvider).apply {
                ZoneRulesProvider.registerProvider(this)
            }
        }
        zoneId = ZoneId.of("America/Los_Angeles")
    }
}

但是当我将导入切换为这样时:threetenjava.time

import java.time.ZoneId
import java.time.zone.TzdbZoneRulesProvider
import java.time.zone.ZoneRulesProvider

然后 Android Studio 显示错误:

Type mismatch
Required: (TypeVariable(T))->TypeVariable(R)
Found: KFunction0<TzdbZoneRulesProvider>

我找不到任何解决此问题的方法。谁能帮我了解这里发生了什么?

Kotlin Java 时 ThreeTenBP

评论


答:

2赞 Sweeper 3/3/2023 #1

无需显式注册 tzdb 提供程序。这是 JVM 的默认提供程序,如 JavaDocs 中所述。

Java 虚拟机有一个默认提供程序,该提供程序为 IANA 时区数据库 (TZDB) 定义的时区提供区域规则。如果定义了系统属性 java.time.zone.DefaultZoneRulesProvider,那么它被视为使用系统类装入器作为缺省提供程序装入的具体 ZoneRulesProvider 类的完全限定名称。如果未定义此系统属性,则将加载系统默认提供程序以用作默认提供程序。

实际上,TzdbZoneRulesProvider 是 中的一个包私有类,因此您无论如何都无法访问它。java.time.zone

这实质上意味着您可以完全删除它:if

if (ZoneRulesProvider.getAvailableZoneIds().isEmpty()) {
    val stream = this.javaClass.classLoader?.getResourceAsStream("TZDB.dat")
    stream.use(::TzdbZoneRulesProvider).apply {
        ZoneRulesProvider.registerProvider(this)
    }
}

如果你的测试依赖于特定版本的 tzdb(比如在极少数情况下,比如这篇文章),你可以使用时区更新工具来更改 JDK 中的 tzdb 版本。此处描述了一个示例。