3

my input String is : 2010-03-24T17:28:50.000Z

output pattern is like:

DateFormat formatter1 = new SimpleDateFormat("EEE. MMM. d. yyyy");

i convert this like this:

formatter1.format(new Date("2010-03-24T17:28:50.000Z"));//illegalArgumentException here the string "2010-03-24T17:28:50.000Z"

ouput should be like this: Thu. Mar. 24. 2010 idea

but i get a illegalArgumentException. Dont know why? any idea??

stacktrace message is:

04-08 19:50:28.326: WARN/System.err(306): java.lang.IllegalArgumentException
04-08 19:50:28.345: WARN/System.err(306):     at java.util.Date.parse(Date.java:447)
04-08 19:50:28.355: WARN/System.err(306):     at java.util.Date.<init>(Date.java:157)
04-08 19:50:28.366: WARN/System.err(306):     at com.example.brown.Bru_Tube$SelectDataTask.doInBackground(Bru_Tube.java:222)
04-08 19:50:28.366: WARN/System.err(306):     at com.example.brown.Bru_Tube$SelectDataTask.doInBackground(Bru_Tube.java:1)
04-08 19:50:28.405: WARN/System.err(306):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-08 19:50:28.415: WARN/System.err(306):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-08 19:50:28.415: WARN/System.err(306):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-08 19:50:28.446: WARN/System.err(306):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-08 19:50:28.456: WARN/System.err(306):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-08 19:50:28.466: WARN/System.err(306):     at java.lang.Thread.run(Thread.java:1096)
Praveen
  • 90,477
  • 74
  • 177
  • 219

2 Answers2

13

The problem is in this part:

new Date("2010-03-24T17:28:50.000Z")

Apparently it doesn't accept dates/times in that format.

You shouldn't be using that constructor anyway - create an appropriate formatter to parse that particular format, and then parse it with that.

Alternatively, use Joda Time to start with, and avoid using DateFormat completely. I don't know if you can use Joda Time from Android, mind you... and it's fairly large.

EDIT: To spell it out explicitly:

String inputText = "2010-03-24T17:28:50.000Z";
// "Z" appears not to be supported for some reason.
DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
inputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
DateFormat outputFormat = new SimpleDateFormat("EEE. MMM. d. yyyy");
Date parsed = inputFormat.parse(inputText);
String outputText = outputFormat.format(parsed);

// Output is Wed. Mar. 24 2010 on my box
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • joda time is not convenient with android. i think so.can we have any other way in java? i mean can we mention the date and time input and output format.and then i convert it. – Praveen Apr 08 '10 at 14:29
  • 2
    SimpleDateFormat has a pattern on its JavaDoc that matches this `yyyy-MM-dd'T'HH:mm:ss.SSSZ` – Powerlord Apr 08 '10 at 14:31
  • 2
    As Jon Skeet says use a SimpleDateFormat to parse the date, similar to how you already use it to format the date. – Andrea Polci Apr 08 '10 at 14:32
  • SimpleDateFormat is the way to go – Mark B Apr 08 '10 at 14:36
  • how to use that? i cant get u people. plz elobrate... :( – Praveen Apr 08 '10 at 14:54
  • 1
    @androidbase: Which bit of it don't you understand? Use `new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")` to create an appropriate date format, then call `format.parse("2010-03-24T17:28:50.000Z")` to get a `Date`. – Jon Skeet Apr 08 '10 at 15:03
  • @OMG Unicorns: Looks like the Z time zone format doesn't support the literal "Z" bizarrely enough. I've set it explicitly... – Jon Skeet Apr 08 '10 at 15:08
  • @Jon Skeet: I was wondering about that, as I didn't see it mentioned on the `SimpleDateFormat` page. I guess I should have tested it. P.S. OMG Unicorns is a parody name, but I can't change it again until May 1st... stupid 30 day rule... *grumble* – Powerlord Apr 08 '10 at 15:35
0

'Z' is not the same as Z

'Z' is just a character literal whereas Z is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).

Therefore, do not use 'Z' in pattern for parsing/formatting.

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards. The Date-Time string, 2010-03-24T17:28:50.000Z conforms to ISO 8601 standards.

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2010-03-24T17:28:50.000Z");

        // Custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE. MMM. d. uuuu", Locale.ENGLISH);
        System.out.println(dtf.format(odt));
    }
}

Output:

Wed. Mar. 24. 2010

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.

Using the legacy API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
        Date date = sdfInput.parse("2010-03-24T17:28:50.000Z");

        // Custom format
        SimpleDateFormat sdfOutput = new SimpleDateFormat("EEE. MMM. d. uuuu", Locale.ENGLISH);
        System.out.println(sdfOutput.format(date));
    }
}

Output:

Wed. Mar. 24. 0003

ONLINE DEMO

Note: Always use Locale with DateTimeFormatter and SimpleDateFormat as these are Locale-sensitive types.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110