Ошибка TripleTen-Backport на Android - ZoneRulesException: файлы данных временной зоны не зарегистрированы
Я использую библиотеку ThreeTen-Backport для моего Android-проекта (потому что 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.
Я искал возможное решение, но не нашел ничего полезного: одно решение предложило мне использовать другую банку, которая включает в себя правила часовых поясов, и другие предположили, что внутри пути к классам могут быть две или более библиотеки 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
Для проекта Android вы должны использовать
implementation 'com.jakewharton.threetenabp:threetenabp:1.0.3'
Убедитесь, что вы вызываете AndroidThreeTen.init(this);
перед использованием классов из библиотеки. Это будет читать данные часовых поясов (включены в библиотеку). Вы можете инициализировать библиотеку в своем классе Application
в методе onCreate
так же, как это рекомендуется в README.
Ответ 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()