DateTimeParseException could not be parsed at index 20

668 Views Asked by At

Why this code worked fine in intellij but throw an exception when running in Android studio?

fun main() {
    val date = "Wed Mar 31 17:27:07 ICT 2021"
    println(date.toEpochSecond())
}

fun String.toEpochSecond(): Long {
    val dbResponsePattern = "EEE MMM dd HH:mm:ss z yyyy"
    val dateTimeFormatter = DateTimeFormatter.ofPattern(dbResponsePattern)
    return ZonedDateTime.parse(this, dateTimeFormatter).toInstant().epochSecond
}

also this one

fun main() {
    val date = "Wed Mar 31 17:27:07 ICT 2021"
    println(date.toEpochSecond())
}

fun String.toEpochSecond(): Long {
    val dbResponsePattern = "EEE MMM dd HH:mm:ss z yyyy"
    val dateTimeFormatter = DateTimeFormatter.ofPattern(dbResponsePattern)
    return Date.from(
            LocalDateTime.parse(this, dateTimeFormatter)
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
    ).toInstant().epochSecond
}

When the exception occurs the text was exact same text i used here.

Exception:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.wo1f.the_earth, PID: 16409
    java.time.format.DateTimeParseException: Text 'Wed Mar 31 17:27:07 ICT 2021' could not be parsed at index 20
        at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
        at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
        at java.time.LocalDateTime.parse(LocalDateTime.java:486)
        at com.wo1f.base_android.DateMapperKt.toEpochSecond(DateMapper.kt:17)
        at com.wo1f.domain.usecases.SyncProfile.syncPost(SyncProfile.kt:46)
        at com.wo1f.domain.usecases.SyncProfile.access$syncPost(SyncProfile.kt:15)
        at com.wo1f.domain.usecases.SyncProfile$invoke$2$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:144)
        at com.wo1f.domain.usecases.SyncProfile$invoke$2$1$invokeSuspend$$inlined$collect$1$1.invokeSuspend(Unknown Source:15)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
1

There are 1 best solutions below

4
On

This can be caused if you are using different version of Timezone database. By default java gets Timezone information from IANA Timezone database, which comes with java installation. this database is subject to change and two different JRE's might be using two different versions of this database. you can verify the database version in use as

java -jar tzupdater.jar -V

It seems the JRE being used by intellij is using outdated IANA Timezone database, which included ICT zone, this must be a version earlier then 2017, as ICT and other invented timezones were removed in 2017 release

Changes to past and future time zone abbreviations

Switch to numeric time zone abbreviations for South America, as part of the ongoing project of removing invented abbreviations. This avoids the need to invent an abbreviation for the new Chilean new zone. Similarly, switch from invented to numeric time zone abbreviations for Afghanistan, American Samoa, the Azores, Bangladesh, Bhutan, the British Indian Ocean Territory, Brunei, Cape Verde, Chatham Is, Christmas I, Cocos (Keeling) Is, Cook Is, Dubai, East Timor, Eucla, Fiji, French Polynesia, Greenland, Indochina

To get the currently available zoneIds, you can enquire the jvm as

java.util.TimeZone.getAvailableIDs()
// or
ZoneId.getAvailableZoneIds()