1

I am receiving data from an API that returns the following date:

"2020-04-15T12:27:22.000Z"

I'm using this method to format the date:

private fun formatarData(dataAtualizacao: String): String {
    var simpleDateFormat = SimpleDateFormat(
        "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
        Locale.getDefault()
    )
    simpleDateFormat.timeZone = TimeZone.getDefault()
    val data = simpleDateFormat.parse(dataAtualizacao)
    return if (data != null) {
        simpleDateFormat = SimpleDateFormat("dd MMM yyyy - HH:mm", Locale.getDefault())
        simpleDateFormat.format(data)
    } else {
        getString(R.string.error)
    }
}

The expected result was "15 abr 2020 - 09:27" but I am receiving the result "15 abr 2020 - 12:27".

How to fix this error?

Vitor Ferreira
  • 1,075
  • 1
  • 14
  • 28
  • As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use java.time, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Apr 15 '20 at 16:30
  • *Never* hardcode `Z` as a literal in the format pattern string. It’s an offset, as you may know, of 0 from UTC and needs to be parsed as an offset or else you get — well, you have discovered already. – Ole V.V. Apr 15 '20 at 16:31
  • Does this answer your question? [ISO 8601 String to Date/Time object in Android](https://stackoverflow.com/questions/3941357/iso-8601-string-to-date-time-object-in-android). Or [this](https://stackoverflow.com/questions/19112357/java-simpledateformatyyyy-mm-ddthhmmssz-gives-timezone-as-ist) or [this](https://stackoverflow.com/questions/49623597/how-to-validate-the-datetime-string-format-2018-01-22t182300-000z-in-java)? – Ole V.V. Apr 15 '20 at 16:33
  • 1
    Does this answer your question? [Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST](https://stackoverflow.com/questions/19112357/java-simpledateformatyyyy-mm-ddthhmmssz-gives-timezone-as-ist) – Ole V.V. Apr 15 '20 at 16:34

1 Answers1

3

As you receive the timestamp in zulu you should parse it in that timezone.

Then, you can change the timezone when formating it as a local date:

private fun formatarData(dataAtualizacao: String): String {
    var simpleDateFormat = SimpleDateFormat(
        "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
        Locale.getDefault()
    )
    simpleDateFormat.timeZone = TimeZone.getTimeZone("UTC")
    val data = simpleDateFormat.parse(dataAtualizacao)
    return if (data != null) {
        simpleDateFormat = SimpleDateFormat("dd MMM yyyy - HH:mm", Locale.getDefault())
        simpleDateFormat.timeZone = TimeZone.getDefault()
        simpleDateFormat.format(data)
    } else {
        getString(R.string.error)
    }
}

By executing println(formatarData("2020-04-15T12:27:22.000Z")) prints 15 abr. 2020 - 14:27 which is the expected time in my local timezone GMT+2.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
  • It’s not the recommended solution. You shouldn’t use `SimpleDateFormat` if there’s a way you can avoid it (which there is), and even if you do, you should parse `Z` as an offset, not as a literal. – Ole V.V. Apr 15 '20 at 16:36