0

I have a time string formatted in Zulu time of "2022-11-21T16:29:28.325Z" and then parsing it for a formatted string in a destination timezone.

try {
    val readLocalDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'")
    readLocalDateFormat.timeZone = TimeZone.getTimeZone("UTC")

    val writeLocalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm")
    writeLocalDateFormat.timeZone = TimeZone.getTimeZone(timeZone)

    return writeLocalDateFormat.format(readLocalDateFormat.parse(dateStr))
} catch (e: Exception) {
    Log.e(TAG, "Failed to parse date: " + dateStr)
    return dateStr
}

In the case, the destination timezone is "America/Halifax" so I would expect the output string to be "2022-11-21 12:29" since Halifax is 4 hours behind UTC time but instead the output is "2022-11-21 12:34" with an additional 5 minutes added to the time. I can't figure out why this 5 minutes is being added. Any ideas?

owenlejeune
  • 135
  • 1
  • 7
  • 1
    Your pattern is wrong: `yyyy-MM-dd'T'HH:mm:ss.sss'Z'` should be `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. If you had used the (new) `java.time` API you'd have got an appropriate exception: `java.lang.IllegalArgumentException: Too many pattern letters: s` – Lino Nov 21 '22 at 17:09
  • Also the additional 5 minutes is just a coincidence. If you use a different input string, you'd get completely different results. – Lino Nov 21 '22 at 17:12
  • 1
    I strongly recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `Instant`, `OffsetDateTime` and `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Nov 21 '22 at 17:38
  • 1
    `Instant.parse("2022-11-21T16:29:28.325Z").atZone(ZoneId.of("America/Halifax")).format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm"))` yields `2022-11-21 12:29`. – Ole V.V. Nov 21 '22 at 18:07
  • @ole-v-v unfortunately I'm working on an Android project with a min API of 23 but Instant requires at least API 26. @lino changing `sss` to `SSS` solves the issue, thanks! – owenlejeune Nov 21 '22 at 19:27
  • 1
    I see. I still recommend that you consider using [desugaring](https://developer.android.com/studio/write/java8-support-table) in order to use java.time for you min API of 23. – Ole V.V. Nov 21 '22 at 19:29
  • 1
    @Lino No, ***never* put quote marks around the `Z`**. That letter means an offset from UTC of zero hours-minutes-seconds. Pronounced “Zulu”. Your quote marks mean "expect, but ignore, this text", a string literal. So you are discarding valuable information. For the correct solution, see the [Comment by Ole V.V.](https://stackoverflow.com/questions/74522382/kotlin-parsing-zulu-date-string-to-utc-date-adds-5-minutes-to-the-time#comment131551051_74522382). – Basil Bourque Nov 21 '22 at 19:41

0 Answers0