0

I am getting UTC time from the server in 2021-06-20T09:56:05.697Z format. I want to format it to user time zone and I tried the below code. But it returns

java.text.ParseException: Unparseable date: "2021-06-20T09:56:05.697Z"

Code used : (dateInString from server as "2021-06-20T09:56:05.697Z")

String dateStr = dateInString;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date dateex = df.parse(dateStr);
df.setTimeZone(TimeZone.getDefault());
String formattedDate = df.format(dateex);
James Z
  • 12,209
  • 10
  • 24
  • 44
Malhotra
  • 221
  • 3
  • 13
  • As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends. See if you either can use [desugaring](https://developer.android.com/studio/write/java8-support-table) or add [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. Jun 22 '21 at 09:06
  • Was my answer helpful? Do you have further doubts or questions? – Ole V.V. Jun 24 '21 at 17:23

1 Answers1

1

java.time through desugaring

Consider using java.time, the modern Java date and time API, for your date and time work. Let’s first declare a formatter for the format we want:

private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z", Locale.ENGLISH);

Now the conversion goes like this:

    String dateStr = "2021-06-20T09:56:05.697Z";

    Instant dateex = Instant.parse(dateStr);
    ZonedDateTime dateTime = dateex.atZone(ZoneId.systemDefault());
    String formattedDate = dateTime.format(FORMATTER);
    
    System.out.println("Formatted date and time: " + formattedDate);

Example output:

Formatted date and time: 2021-06-20 05:56:05 AST

This was running on a computer in America/Tortola time zone, and we see that the date and time have been converted to Atlantic Standard Time as requested.

I am exploiting the fact that the string from the server is in ISO 8601 format, a format that the classes of java.time generally parse natively without any explicit formatter.

What went wrong in your code?

When parsing the string from the server, if using a formatter for it, that formatter needs to know the format to be parsed. It doesn’t help that it knows the format to be formatted into later.

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
  • I think you don't need to create a Formatter. I think there are already static ones you can use with the normal formats (I am not in front of android studio now, but I think it was `DateTimeFormatter.ISO_DATE` or similar, that has that particular format. – Martin Marconcini Jun 22 '21 at 14:01
  • @MartinMarconcini Thank you for your comment. It depends on what you mean. For parsing the ISO format from the server we don’t need any formatter, and I am not creating any either. If we want output like `2021-06-20 05:56:05 AST`, then no provided formatter gives us that, which is why I created one for this purpose. Of course we might instead just print the `ZonedDateTime` without formatting it first, getting output like `2021-06-20T05:56:05.697-04:00[America/Tortola]`. Many users would not be quite happy … – Ole V.V. Jun 22 '21 at 14:22