web-dev-qa-db-fra.com

Erreur ThreeTen-Backport sur Android - ZoneRulesException: aucun fichier de données de fuseau horaire enregistré

J'utilise la bibliothèque ThreeTen-Backport pour mon Android (car Java.time n'est pas encore implémenté dans Android)).

Lorsque j'écris LocalDate today=LocalDate.now(); ou LocalTime time=LocalTime.now(); j'obtiens l'exception suivante:

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)

La même ligne de code fonctionne bien dans un autre projet Java que j'ai, qui utilise la bibliothèque native Java.time.

J'ai cherché une solution possible mais je n'ai rien trouvé d'utile: une solution m'a suggéré d'utiliser un autre jar qui inclut les règles de fuseau horaire et l'autre a suggéré qu'il pourrait y avoir deux bibliothèques ThreeTenBP ou plus à l'intérieur du chemin de classe.
Ces cas ne correspondent pas à mon cas.

Dans le fichier build.gradle, Dans la section des dépendances, j'ai essayé quelques configurations:

  • Au début, j'ai utilisé - compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
  • Ensuite, j'ai essayé - compile 'org.threeten:threetenbp:1.0.3'
  • Après cela, j'ai essayé - compile 'org.threeten:threetenbp:1.3.1'
  • Actuellement, j'utilise compile 'org.threeten:threetenbp:1.3.2'

Je ne sais pas ce qui ne va pas avec cette ligne de code et comment y remédier.
Les méthodes LocalDate.now() et LocalTime.now() doivent fonctionner sans spécifier de fuseau horaire.

29
Matan Itzhak

Pour Android vous devez utiliser

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

Assurez-vous d'appeler AndroidThreeTen.init(this); avant d'utiliser les classes de la bibliothèque. Cela lira les données de fuseaux horaires (incluses dans la bibliothèque). Vous pouvez initialiser la bibliothèque dans votre classe Application dans la méthode onCreate comme il est recommandé dans le readme .

59
LordRaydenMK

Au lieu d'initialiser la bibliothèque, vous pouvez essayer ceci:

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)

Usage:

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