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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38281808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:17:15  来源:igfitidea点击:

ThreeTen-Backport error on Android - ZoneRulesException: No time-zone data files registered

javaandroidexceptionjsr310threetenbp

提问by Matan Itzhak

I'm using ThreeTen-Backport library for my Android project (because java.time is not yet implemented in android development).

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

When I write LocalDate today=LocalDate.now();or LocalTime time=LocalTime.now();I get the following exception:

当我写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)

The same line of code works well in another java project I have, which uses the native java.time library.

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

I searched for a possible solution but couldn't find anything useful: one solution suggested I need to use another jar that includes the time-zone rules and other suggested that there might be two or more ThreeTenBP-libraries inside the classpath.
Those cases don't match my case.

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

Inside the build.gradlefile, at the dependencies section, I've tried few configurations:

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

  • At first, I used - compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
  • Then, I tried - compile 'org.threeten:threetenbp:1.0.3'
  • After that, I tried - compile 'org.threeten:threetenbp:1.3.1'
  • Currently, I use compile 'org.threeten:threetenbp:1.3.2'
  • 起初,我使用 - 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'

I don't know what is wrong with that line of code and how to fix it.
The LocalDate.now()and LocalTime.now()methods should work without specifying a time zone.

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

回答by LordRaydenMK

For Android project you should use

对于 Android 项目,您应该使用

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

Make sure you call AndroidThreeTen.init(this);before using the classes from the library. This will read the time zones data (included in the library). You can initialize the library in your Applicationclass in the onCreatemethod just like it is recommended in the README.

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

回答by Micha? Jab?oński

For me, it wasn't working on signed release build with proguard enabled. Check your proguard rules if they contain

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

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

unless, add it. It helped for me.

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

回答by android developer

Instead of initialization of the library, you can try this:

你可以试试这个,而不是初始化库:

LocalDateEx.kt

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

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

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)

Usage:

用法:

   val today=LocalDateEx.getNow()
   val today2=LocalTimeEx.getNow()
   val today3=LocalDateTimeEx.getNow()