1

I'm getting an unparseable date exception using:

"2021-07-20T12:35:20-07:00".toDate()!!

@SuppressLint("SimpleDateFormat")
fun String.toDate() : Date? {
    return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(this)
}
SomeKoder
  • 575
  • 4
  • 14
  • 2
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `OffsetDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). It parses your string without you specifying any formatter. – Ole V.V. Aug 17 '21 at 04:20
  • Does this answer your question? [Android DateTime parse](https://stackoverflow.com/questions/23902492/android-datetime-parse) – Ole V.V. Aug 17 '21 at 04:24

2 Answers2

3

From the SimpleDateFormat docs

Z     Time zone   RFC 822 time zone   -0800
X     Time zone   ISO 8601 time zone  -08; -0800; -08:00

The Z directive expects the time zone to be specified without a colon, whereas X allows a colon. Either format your dates like

2021-07-20T12:35:20-0700

or use the ISO 8601 timezone designator, rather than the RFC 822 one

yyyy-MM-dd'T'HH:mm:ssX

Try it online!

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
1

java.time through desugaring

I recommend that you uses java.time, the modern Java date and time API, for your date and time work. Excuse my Java syntax:

public static OffsetDateTime toDate(String s) {
    return OffsetDateTime.parse(s);
}

Let’s try it:

    OffsetDateTime dateTime = toDate("2021-07-20T12:35:20-07:00");
    System.out.println(dateTime);

Output is:

2021-07-20T12:35:20-07:00

We do not need to specify any formatter at all. Your string is in ISO 8601 format. OffsetDateTime and the other classes of java.time parse the most common variants of ISO 8601 as their default, that is, without any explicit formatter. Which is good because as you experienced, constructing a formatter is error-prone.

In case you need a Date object for an old API not yet upgraded to Java time, the conversion is:

    Date oldfashionedDate = Date.from(dateTime.toInstant());
    System.out.println(oldfashionedDate);

Output (from a device in Europe/Brussels time zone):

Tue Jul 20 21:35:20 CEST 2021

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161