50

我正在为我的 Android 项目使用 ThreeTen-Backport 库(因为 java.time 尚未在 android 开发中实现)。

当我写LocalDate today=LocalDate.now();LocalTime time=LocalTime.now();我得到以下异常:

Caused by: org.threeten.bp.zone.ZoneRulesException: 
  No time-zone data files registered   
      at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:176)
      at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:133)
      at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
      at org.threeten.bp.ZoneId.of(ZoneId.java:357)
      at org.threeten.bp.ZoneId.of(ZoneId.java:285)
      at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:244)
      at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137)
      at org.threeten.bp.LocalDate.now(LocalDate.java:165)

同一行代码在我拥有的另一个 java 项目中运行良好,该项目使用本机 java.time 库。

我搜索了一个可能的解决方案,但找不到任何有用的解决方案:一个解决方案建议我需要使用另一个包含时区规则的 jar,而其他解决方案建议类路径中可能有两个或多个 ThreeTenBP 库。
这些案例与我的案例不符。

build.gradle文件的依赖项部分,我尝试了一些配置:

  • 起初,我使用 -compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
  • 然后,我尝试了- compile 'org.threeten:threetenbp:1.0.3'
  • 之后,我尝试了- compile 'org.threeten:threetenbp:1.3.1'
  • 目前,我使用compile 'org.threeten:threetenbp:1.3.2'

我不知道那行代码有什么问题以及如何修复它。and方法应该在不指定时区的情况下工作
LocalDate.now()LocalTime.now()

4

5 回答 5

109

对于 Android 项目,您应该使用

implementation 'com.jakewharton.threetenabp:threetenabp:1.0.3'

确保AndroidThreeTen.init(this);在使用库中的类之前调用​​。这将读取时区数据(包含在库中)。您可以在方法中初始化Application类中的库,onCreate就像在README中推荐的那样。

于 2016-07-09T12:38:04.903 回答
2

您可以尝试以下操作,而不是初始化库:

LocalDateEx.kt

object LocalDateEx {
    /**an alternative of LocalDate.now(), as it requires initialization using AndroidThreeTen.init(context), which takes a bit time (loads a file)*/
    @JvmStatic
    fun getNow(): LocalDate = Calendar.getInstance().toLocalDate()
}

fun Calendar.toLocalDate(): LocalDate = LocalDate.of(get(Calendar.YEAR), get(Calendar.MONTH) + 1, get(Calendar.DAY_OF_MONTH))

LocalTimeEx.kt

object LocalTimeEx {
    /**an alternative of LocalDateTime.now(), as it requires initialization using AndroidThreeTen.init(context), which takes a bit time (loads a file)*/
    @JvmStatic
    fun getNow(): LocalTime = Calendar.getInstance().toLocalTime()
}

fun Calendar.toLocalTime(): LocalTime = LocalTime.of(get(Calendar.HOUR_OF_DAY), get(Calendar.MINUTE), get(Calendar.SECOND), get(Calendar.MILLISECOND) * 1000000)

LocalDateTimeEx.kt

object LocalDateTimeEx {
    /**an alternative of LocalDateTime.now(), as it requires initialization using AndroidThreeTen.init(context), which takes a bit time (loads a file)*/
    @JvmStatic
    fun getNow(): LocalDateTime = Calendar.getInstance().toLocalDateTime()
}

private fun Calendar.toLocalDateTime(): LocalDateTime = LocalDateTime.of(get(Calendar.YEAR), get(Calendar.MONTH) + 1, get(Calendar.DAY_OF_MONTH), get(Calendar.HOUR_OF_DAY), get(Calendar.MINUTE), get(Calendar.SECOND),
        get(Calendar.MILLISECOND) * 1000000)

用法:

   val today=LocalDateEx.getNow()
   val today2=LocalTimeEx.getNow()
   val today3=LocalDateTimeEx.getNow()
于 2018-03-22T12:38:10.400 回答
1

对我来说,它不适用于启用 proguard 的签名版本构建。检查您的 proguard 规则是否包含

-keep class org.threeten.bp.zone.*

除非,添加它。它对我有帮助。

于 2020-02-28T09:42:42.423 回答
1

AGP 4.0 现在支持 Java 8 Desugar API,请参见此处:https ://developer.android.com/studio/write/java8-support

因此,您可以java.time.在不使用反向移植版本的情况下使用

笔记:

如果您尝试支持低于 21 的 API(由 解决minSdk 21)仍然存在问题:https ://github.com/google/bundletool/issues/182#issuecomment-753269941

如官方文档中所述,脱糖还会增加构建时间

为了支持这些语言 API,该插件编译了一个单独的 DEX 文件,其中包含缺少的 API 的实现并将其包含在您的应用程序中。脱糖过程会重写您的应用程序代码,以在运行时使用此库。

于 2021-01-11T11:42:07.887 回答
0

当我使用 API 25时, java.time不起作用。使用 Jake Wharton 的threetenadp 做到了。所以这里有一个小更新,可以在 Studio 2020.3.1 上使用它

在模块 build.gradle

dependencies {
 implementation 'com.jakewharton.threetenabp:threetenabp:1.3.1'
}

import com.jakewharton.threetenabp.AndroidThreeTen

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    AndroidThreeTen.init(application);

当 IDE 要求导入时,请务必选择com.jakewharton.threetenabp.AndroidThreeTen而不是java.time

LocalTime.now().toSecondOfDay() 是我需要的。

于 2021-11-04T01:10:07.117 回答