Error parsing date string - java

I need to parse this string as a date:
Mon Jun 10 00:00:00 CEST 2013
Here is what I do:
SimpleDateFormat sdf = new SimpleDateFormat("ccc MMM dd HH:mm:ss z yyyy");
Date date = sdf.parse(dateString);
But I get a ParseException:
Unparseable date: "Wed Oct 02 00:00:00 CEST 2013" (at offset 0)
Any help please?

As others have said, you need EEE instead of ccc - but you should also specify a locale, so that it doesn't try to parse the month and day names (and other things) using your system default locale:
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",
Locale.US);

Your format is wrong. You need to use EEE instead of ccc, where E means Day name in week.
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Have a look at the docs regarding all the valid patterns available for SimpleDateFormat.

Replace ccc with EEE in the pattern to specify the day of the week:
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Example: https://gist.github.com/kmb385/8781482

Update the format as below :
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");

It is a Locale problem. That's because dates are represented differently between Locales, so the JVM fires an exception if the Date is not in the correct format. You can solve it by setting a custom Locale:
String str = "Mon Jun 10 00:00:00 EST 2013";
Locale.setDefault(Locale.US);
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date date = sdf.parse(str);
System.out.println(date);
IDEone examples do work because the default locale is Locale.US

java.time
The accepted answer uses SimpleDateFormat which was the correct thing to do in Feb 2014. In Mar 2014, the java.util date-time API and their formatting API, SimpleDateFormat were supplanted by the modern Date-Time API. Since then, it is highly recommended to stop using the legacy date-time API.
Note: Never use date-time formatting/parsing API without a Locale.
Solution using the modern date-time API:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
class Main {
public static void main(String[] args) {
String stdDateTime = "Mon Jun 10 00:00:00 CEST 2013";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(stdDateTime, parser);
System.out.println(zdt);
}
}
Output:
2013-06-10T00:00+02:00[Europe/Paris]
If for any reason, you need an instance of java.util.Date, you can get it as follow:
Date date = Date.from(zdt.toInstant());
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.

Related

Java parse date from string with GMT string

I have the following date string Tue Feb 04 2020 16:11:25 GMT+0200 (IST) where I'm trying to convert into date time using the following code:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
And I got the following exception:
Text Tue Feb 04 2020 16:11:25 GMT+0200 (IST) could not be parsed at index 28
I look at the following SO question Java string to date conversion and I see that
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
So why I got the exception?
The following pattern works.
"E MMM d u H:m:s 'GMT'Z (z)"
You can replace Z with x or X for the same result.
You can spell it out, if you want, but it is not necessary.
"EEE MMM dd uuuu HH:mm:ss 'GMT'ZZZ (zzz)"
You should parse that input to an OffsetDateTime, since the input string includes a Date, a Time, and an Offset.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM d u H:m:s 'GMT'Z (z)", Locale.ENGLISH);
OffsetDateTime dateTime = OffsetDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
System.out.println(dateTime);
Output
2020-02-04T16:11:25+02:00
One of the reasons is that you are trying to parse a datetime String (date, time, zone and offset) to an object (LocalDate) that only stores year, month and day, nothing more.
Use a suitable class, say ZonedDateTime and adjust the parsing pattern a little:
you can't use the localized offset O because in a DateTimeFormatter it doesn't support the formatting your String has, which is GMT+0200 and the formatter supports GMT+8; GMT+08:00; UTC-08:00; only (mind the colon). Use a combination of an escaped GMT plus a regular offset symbol x
you have a single d but a representation of days that will always have two digits, so you need to use dd
you have to escape the brackets the zone abbreviation is enclosed in and I think a single z is sufficient for such an abbreviation
Considering all these aspects, you could parse the String as follows:
public static void main(String[] args) {
String parsePattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'x '('z')'";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePattern,
Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
System.out.println(zdt);
}
which then outputs (using the default formatter for ZonedDateTime)
2020-02-04T16:11:25+02:00[Asia/Jerusalem]
The problem here is the GMT+0200 if you use: GMT+02 it works.
But as already mentioned in the comments it is a little confusing that you use a variable called dateTime on something of the type LocalDate.
So your result will be only the date 2020-02-04 because LocalDate can only save this kind of data.
2 things - ZonedDateTime & missing ':' for 0
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)");
ZonedDateTime dateTime = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+02:00 (IST)", formatter);
This should work
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss 'GMT'Z (z)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
Do not use a fixed text for the timezone:
Do not use a fixed text (e.g. 'GMT') for the timezone as mentioned in the existing answers because that approach may fail for other locales.
The recommended solution:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Tue Feb 04 2020 16:11:25 GMT+0200 (IST)";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d u H:m:s VVZ (z)", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
Output:
2020-02-04T14:11:25Z[Atlantic/Reykjavik]
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
you wrote one d and you passed 04 you should write dd instead of d like the following
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);

Joda: parse string as DateTime with weird timezone format

Is there a valid joda DateTimeFormat for date strings like the following:
Mon, 23 Jul 2018 07:08:26 +0300 GMT
I have tried:
DateTimeFormatter FMT1 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z");
DateTimeFormatter FMT2 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss z");
DateTimeFormatter FMT3 = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss z Z");
but none of these work.
I had a look in here https://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html and I cannot figure out a way to parse that date without having to change the string itself first.
Is there a way?
I take it that +0300 is the true offset and GMT is just there to say that +0300 is relative to GMT. Joda-Time supports apostrophes for delimiting constant text that shouldn’t be interpreted:
DateTimeFormatter formatter = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z 'GMT'");
DateTime dt = DateTime.parse("Mon, 23 Jul 2018 07:08:26 +0300 GMT", formatter);
System.out.println(dt);
Output on my computer in Europe/Copenhagen time zone:
2018-07-23T06:08:26.000+02:00
As an aside the idea of using a lowercase and an uppercase z wasn’t too bad. It works if you put them in the opposite order:
DateTimeFormatter formatter = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss Z z");
2018-07-23T04:08:26.000Z
I prefer the apostrophes, though. It’s hard for a reader to know what to expect from Z z.

How to Parse Date in java [duplicate]

This question already has answers here:
How can I convert Date.toString back to Date?
(5 answers)
Closed 4 years ago.
Unparseable date: "Tue Jul 03 16:59:51 IST 2018" Exception
String date="Tue Jul 03 16:59:51 IST 2018";
i want to parse it.
My code is
SimpleDateFormat newformat=SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
Date d=newformat.parse(date);
You are using old and quite problematic classes, especially Date.
For your example, perhaps consider using LocalDateTime
String date = "Tue Jul 03 16:59:51 IST 2018";
DateTimeFormatter format = DateTimeFormatter
.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
LocalDateTime dateTime = LocalDateTime.parse(date, format);
Since your pattern has to match the string you want to parse you need to adjust the pattern as following:
EEE MMM dd HH:mm:ss z yyyy
Infos gathered from the docs.
You should also use the new java.time API introduced with Java 8.
String s = "Tue Jul 03 16:59:51 IST 2018";
//Java 7 way
SimpleDateFormat newformat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date d = newformat.parse(s);
//Java 8 way
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
LocalDateTime dateTime = LocalDateTime.parse(s, formatter);

Parse a String to Date in Java

I'm trying to parse a string to a date, this is what I have:
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zZ (zzzz)");
Date date = new Date();
try {
date = sdf.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
the string to parse is this:
Sun Jul 15 2012 12:22:00 GMT+0300 (FLE Daylight Time)
I followed the http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Pretty sure I've done everything by the book. But it is giving me ParseException.
java.text.ParseException: Unparseable date:
"Sun Jul 15 2012 12:22:00 GMT+0300 (FLE Daylight Time)"
What am I doing wrong? Patterns I Have tried:
EEE MMM dd yyyy HH:mm:ss zzz
EEE MMM dd yyyy HH:mm:ss zZ (zzzz)
You seem to be mixing the patterns for z and Z. If you ignore the (FLE Daylight Time), since this is the same info as in GMT+0300, the problem becomes that SimpleDateFormat wants either GMT +0300 or GMT+03:00. The last variant can be parsed like this:
String time = "Sun Jul 15 2012 12:22:00 GMT+03:00 (FLE Daylight Time)";
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zzz");
Date date = sdf.parse(time);
[EDIT]
In light of the other posts about their time strings working, this is probably because your time string contains conflicting information or mixed formats.
java.time
I should like to contribute the modern answer. Use java.time, the modern Java date and time API, for your date and time work.
First define a formatter for parsing:
private static final DateTimeFormatter PARSER = DateTimeFormatter
.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z (", Locale.ROOT);
Then parse in this way:
String time = "Sun Jul 15 2012 12:22:00 GMT+0300 (FLE Daylight Time)";
TemporalAccessor parsed = PARSER.parse(time, new ParsePosition(0));
OffsetDateTime dateTime = OffsetDateTime.from(parsed);
System.out.println(dateTime);
Output is:
2012-07-15T12:22+03:00
I am not parsing your entire string, but enough to establish a point in time and an offset from GMT (or UTC). Java cannot parse the time zone name FLE Daylight Time. This is a Microsoft invention that Java does not know. So I parse up to the round bracket before FLE in order to validate this much of the string. To instruct the DateTimeFormatter that it needs not parse the entire string I use the overloaded parse method that takes a ParsePosition as second argument.
From Wikipedia:
Sometimes, due to its use on Microsoft Windows, FLE Standard Time (for
Finland, Lithuania, Estonia, or sometimes Finland, Latvia, Estonia) …
are used to refer to Eastern European Time.
If you indispensably need a Date object, typically for a legacy API that you cannot afford to upgrade to java.time just now, convert like this:
Date oldfashionedDate = Date.from(dateTime.toInstant());
System.out.println(oldfashionedDate);
Output when run in Europe/Tallinn time zone:
Sun Jul 15 12:22:00 EEST 2012
What went wrong in your code?
Your SimpleDateFormat successfully parsed GMT+03 into a “time zone” matching the small z in the format pattern string. It then tried to parse the remaining 00 into an offset to match the capital Z. Since an offset requires a sign, this failed.
What am I doing wrong?
As others have said, you should not try to parse GMT into a time zone abbreviation. GMT can be used as a time zone abbreviation; but your time is not in GMT. So you don’t want that. It would only be misleading. Had you been successful, you would rather have risked an incorrect result because you had parsed a time zone that was incorrect for your purpose.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Eastern European Time on Wikipedia.
Try it this way..
System.out.println(new SimpleDateFormat(
"EEE MMM dd yyyy HH:mm:ss zZ (zzzz)").format(new Date()));
Output i got:
Thu Jul 12 2012 12:41:35 IST+0530 (India Standard Time)
You can try to print the date format string :
/**
* #param args
*/
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat(
"EEE MMM dd yyyy HH:mm:ss zZ (zzzz)");
Date date = new Date();
try {
//
System.out.println(sdf.format(date));
date = sdf.parse(time);
} catch (Exception e) {
e.printStackTrace();
}
}
If you have problems with locales, you can either set the default Locale for the whole application
Locale.setDefault(Locale.ENGLISH);
or just use the english locale on your SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zZ (zzzz)", Locale.ENGLISH);
You can also use Locale.US or Locale.UK.

Why does this SimpleDataFormat parsing fail on Android?

DateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy");
sdf.parse("Sun Dec 13 10:00:00 UTC 2009")
result
java.text.ParseException: Unparseable date: Sun Dec 13 10:00:00 UTC
2009
Note: This code seems to work in a normal Java application but seems to fail on Android.
It doesn't for me - perhaps your default locale uses different month names? Specify the locale for the format.
// Will definitely work
DateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy",
Locale.US);
// Will definitely not work
DateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy",
Locale.FRANCE);
// Might work - depends on default locale
DateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy")
(The problem is the names of the days of the week and months of the year, which are obviously culture-specific. Date and time separators can vary too.)
EDIT: It's odd that you're still having problems. Just to check, please try to run the following short but complete program:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class Test {
public static void main(String[] args) throws Exception {
DateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy",
Locale.US);
sdf.parse("Sun Dec 13 10:00:00 UTC 2009");
}
}
If that doesn't work, try taking out the time zone part of both the pattern and the text. I wonder whether it's having problems with that.
EDIT: If the Android SimpleDateFormat implementation doesn't manage to parse the time zone, you can probably just use:
text = text.replace(" UTC ", " ");
Date parsed = sdf.parse(text);
... having set the time zone on the parser to UTC, of course. You probably want to check that it contains " UTC " first, just in case your data format changes.
Your format looks correct. Is it possible that you are not using an English Locale though? The formatter will take your system locale and this could result in different names for 'sun' and 'dec'

Categories

Resources