Как решить ExceptionInInitializerError и ZoneRulesException в ThreeTenABP?

Я пытаюсь преобразовать время сервера (GMT + 09:00) в местное время (любые регионы клиента).

Я пробовал java.time. Однако для этого требуется как минимум minSdk API26. Тогда я искал альтернативный способ

Итак, я использовал библиотеку тридесятьABP.

Я получаю это исключение.

java.lang.ExceptionInInitializerError
        at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:121)
        at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
        at org.threeten.bp.ZoneId.of(ZoneId.java:358)

В onBindViewHolder() адаптера.

        val item = datas?.get(position)

        AndroidThreeTen.init(context)

        val checkedDate = item?.datetime
        val serverTimeZone = ZoneId.of("Asia/Tokyo")
        val serverFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss")
        val clientTimeZone = ZoneId.systemDefault()

        val serverDateTime = LocalDateTime.parse(checkedDate, serverFormatter).atZone(serverTimeZone)
        val clientDateTime = serverDateTime.withZoneSameInstant(clientTimeZone)

Кроме того, не похоже, что он предлагает все часовые пояса. Если я загляну в ZoneId, я увижу это ниже:

    static {
        Map<String, String> base = new HashMap();
        base.put("ACT", "Australia/Darwin");
        base.put("AET", "Australia/Sydney");
        base.put("AGT", "America/Argentina/Buenos_Aires");
        base.put("ART", "Africa/Cairo");
        base.put("AST", "America/Anchorage");
        base.put("BET", "America/Sao_Paulo");
        base.put("BST", "Asia/Dhaka");
        base.put("CAT", "Africa/Harare");
        base.put("CNT", "America/St_Johns");
        base.put("CST", "America/Chicago");
        base.put("CTT", "Asia/Shanghai");
        base.put("EAT", "Africa/Addis_Ababa");
        base.put("ECT", "Europe/Paris");
        base.put("IET", "America/Indiana/Indianapolis");
        base.put("IST", "Asia/Kolkata");
        base.put("JST", "Asia/Tokyo");
        base.put("MIT", "Pacific/Apia");
        base.put("NET", "Asia/Yerevan");
        base.put("NST", "Pacific/Auckland");
        base.put("PLT", "Asia/Karachi");
        base.put("PNT", "America/Phoenix");
        base.put("PRT", "America/Puerto_Rico");
        base.put("PST", "America/Los_Angeles");
        base.put("SST", "Pacific/Guadalcanal");
        base.put("VST", "Asia/Ho_Chi_Minh");
        base.put("EST", "-05:00");
        base.put("MST", "-07:00");
        base.put("HST", "-10:00");
        SHORT_IDS = Collections.unmodifiableMap(base);
    }

Итак, когда я нахожусь в Сеуле, Корее («Азия/Сеул») или где-то еще, где карта base не включает, я не знаю, работает ли она правильно или нет. Если я удалю AndroidThreeTen.init(context), я получу это ниже:

org.threeten.bp.zone.ZoneRulesException: No time-zone data files registered
        at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:165)
        at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:122)
        at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
        at org.threeten.bp.ZoneId.of(ZoneId.java:358)

Статический инициализатор инициализирует SHORT_IDS, карту устаревших сокращений часовых поясов, так что это, конечно, не предназначено для хранения всех часовых поясов.

Ole V.V. 25.06.2019 06:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
284
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно вызвать AndroidThreeTen.init(context) в методе Application onCreate(), а не в onBindViewHolder()

class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()

        AndroidThreeTen.init(this@App)
    }
}

Не забудьте зарегистрировать свое приложение для манифеста

<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
          package = "com.example.app">

    <application
            android:name = ".MyApp"
                <!-- .... -->
            >

    </application>

</manifest>

Другие вопросы по теме