4

I'm trying to parse a string date to a date . My string date is : 2021-12-16T11:00:00.000Z.

I have the follwing code to parse it to a date object:

val stringDate = "2021-12-16T16:42:00.000Z"
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
var consultationDate = sdf.parse(stringDate)

And I keep getting this error:

java.text.ParseException: Unparseable date: "2021-12-16T11:00:00.000Z"
Mario Muresean
  • 233
  • 1
  • 5
  • 16

2 Answers2

6

You should use Z the same way you use T for the parser to recognize the character in format

val stringDate = "2021-12-16T16:42:00.000Z"
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
var consultationDate = sdf.parse(stringDate)
  • I don’t know how SimpleDateFormat works but this seems wrong. You should never escape/ignore the Z. It means UTC timezone . If you escape it you will be discarding the timezone information from the date. Try to parse with yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX or yyyy-MM-dd'T'HH:mm:ss.SSSXXXX. – Leo Dabus Dec 18 '21 at 05:21
  • Seems like you can not use more than 3 X with SimpleDateFormat. Not sure what you need to pass for the timezone if Z is not working but make sure the parsing is not discarding the UTC timezone. As it is it seems to me that it will parse it using the current timezone. – Leo Dabus Dec 18 '21 at 05:34
  • Try using XXX or XX. if you want to escape the Z you need to set the timezone of the parser to UTC and make sure the timezone always comes with Z. maybe this post helps https://stackoverflow.com/a/3914498/2303865 – Leo Dabus Dec 18 '21 at 05:40
5

As @Leo Dabus mentioned You should never escape/ignore the Z. It means UTC timezone . - as it will parse it using current timezone.

Also you shouldn't be using SimpleDateFormat as it's outdated

Use ZonedDateTime and OffsetDateTime to parse the date in the specific zone.

val date = "2021-12-16T16:42:00.000Z" // your date
// date is already in Standard ISO format so you don't need custom formatted
val dateTime : ZonedDateTime = OffsetDateTime.parse(date).toZonedDateTime()  // parsed date 
// format date object to specific format if needed
val formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm") 
Log.e("Date 1", dateTime.format(formatter)) // output : Dec 16, 2021 16:42

Above date in the UTC timezone, if you want you can convert it into your system default timezone using withZoneSameInstant

val defaultZoneTime: ZonedDateTime = dateTime.withZoneSameInstant(ZoneId.systemDefault())
Log.e("Date 1", defaultZoneTime.format(formatter)) // output : Dec 16, 2021 22:12

Note: ZonedDateTime only works in android 8 and above, to use it below android 8 enable desugaring.

In your app module's build.gradle, add coreLibraryDesugaringEnabled

 compileOptions {
        // Flag to enable support for the new language APIs
        coreLibraryDesugaringEnabled true
        // Sets Java compatibility to Java 8
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
Nitish
  • 3,075
  • 3
  • 13
  • 28