4

I want to parse this date in this format 2021-11-03T14:09:31.135Z (message.created_at)

My code is this:

val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS")
var convertedDate = Date()
try {
    convertedDate = dateFormat.parse(message.created_at)
} catch (e: ParseException) {
    e.printStackTrace()
}

It is failing to parse

Suryakant Bharti
  • 673
  • 1
  • 6
  • 24
  • 2
    `SimpleDateFormat` and `Date` are part of the legacy Java time APIs. `java.time` is the modern replacement and is part of Java 8. In Android it's only available in [API level 26 and up](https://developer.android.com/reference/java/time/package-summary), **but** it can be used almost entirely in earlier versions using [API desugaring](https://developer.android.com/studio/write/java8-support-table). Please consider switching to `java.time`. It's just plain better. – Joachim Sauer Nov 16 '21 at 11:17
  • Yes, other people are also suggesting this. Will have a look at it. – Suryakant Bharti Nov 16 '21 at 11:37

5 Answers5

8

Don't use SimpleDateFormat it's long outdated and troublesome.
Use DateTimeFormatter to parse the date.

 fun parseDate() {
        var formatter: DateTimeFormatter? = null
        val date = "2021-11-03T14:09:31.135Z" // your date string
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX") // formatter
            val dateTime: ZonedDateTime = ZonedDateTime.parse(date, parser) // date object
            val formatter2: DateTimeFormatter =
                DateTimeFormatter.ofPattern("EEEE, MMM d : HH:mm") // if you want to convert it any other format
            Log.e("Date", "" + dateTime.format(formatter2))
        }
    }

Output: Wednesday, Nov 3 : 14:09

To use this below android 8 , use desugaring

Nitish
  • 3,075
  • 3
  • 13
  • 28
  • Problem is solved by previous answers. Thanks for help. – Suryakant Bharti Nov 16 '21 at 11:12
  • 2
    SuryakantBharti , that's great , but I will still suggest you migrate to modern java api - referring to @deHarr answer or mine, You can read about [reason by new date time api were formed](https://stackoverflow.com/questions/9277747/android-simpledateformat-how-to-use-it) , answer by Arwind Kumar , or a google search might give you more reasons – Nitish Nov 16 '21 at 11:22
  • 1
    Thanks a lot. I will have a look into it. – Suryakant Bharti Nov 16 '21 at 11:29
  • 1
    This is definitely using the most modern API. I just think the approach to treat `Z` as a literal by escaping it via single quotes although it means *UTC* is quite a hack. The `String` clearly denotes a date and time plus offset, which is reflected by the class `OffsetDateTime` and only partially by `LocalDateTime` which doesn't hold information about a zone. If one really needs a `LocalDateTime` one could always call `toLocalDateTime()` from an instance of `OffsetDateTime`. – deHaar Nov 16 '21 at 12:15
3

try it


fun main() {
    val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS")
    var convertedDate = Date()
    try {
        convertedDate = dateFormat.parse("2021-11-03T14:09:31.135Z")
        println(convertedDate)
    } catch (e: ParseException) {
        e.printStackTrace()
    }
}

Future Deep Gone
  • 831
  • 6
  • 16
2

Well, the format not entirely what the string looks like:

  • You have a space instead of the T literal between the date and the time
  • You have no offset notation at the end
  • You are using hh, which is 12-hour format. Use HH instead.

This format should do it:

yyyy-MM-dd'T'HH:mm:ss.SSSX

However, note that Date and SimpleDateFormat are obsolete and troublesome. Use java.time instead. If your Android API level appears to be too low, you could use ThreeTen Backport.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
2

If your minimum API level is 21, you can use API Desugaring, find some nice explanations about it here.

As soon as you have enabled API Desugaring, you can directly parse your ISO String to an OffsetDateTime:

val convertedDate = OffsetDateTime.parse(message.created_at)
deHaar
  • 17,687
  • 10
  • 38
  • 51
0

You have just missed "T" in the date format string. use this solution for your date parsing.

fun formatDate(inputDate: String) {
    var convertedDate = Date()
    val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ", Locale.getDefault())
    try {
        convertedDate = dateFormat.parse(inputDate)
        print("Parsed date $convertedDate")
    } catch (ignored: ParseException) {
    }

    //if you wish to change the parsed date into another formatted date
    val dfOutput = SimpleDateFormat("dd-MMM-yyyy", Locale.getDefault())
    val str :String = dfOutput.format(convertedDate)
    print("Formatted date $str")
}

Just pass your "message.created_at" as an input parameter. For more date time formats check out this official documentation of Android Developers site. SimpleDateFormat | Android Developers you will get all the possible date formats here.

Cheers..!

Rohan Shinde
  • 374
  • 1
  • 6
  • 16