Android 上的 ThreeTen-Backport 错误 - ZoneRulesException:未注册时区数据文件

2022-08-31 20:26:48

我正在为我的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'

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


答案 1

对于安卓项目,你应该使用

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

请确保在使用库中的类之前调用。这将读取时区数据(包含在库中)。您可以在方法中初始化类中的库,就像在自述文件中建议的那样。AndroidThreeTen.init(this);ApplicationonCreate


答案 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()