Why does this SimpleDataFormat parsing fail on Android? - java

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'

Related

Year end date (java.util.Date) converted to string as wrong date [duplicate]

I am trying to convert EEE MMM dd HH:mm:ss ZZZ yyyy to YYYY-MM-DD format, so I can insert it into a MySQL database. I do not get any error, but the date inserted into my db is wrong and the same for every row...
String date = Sat Mar 04 09:54:20 EET 2017;
SimpleDateFormat formatnow = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
SimpleDateFormat formatneeded=new SimpleDateFormat("YYYY-MM-DD");
java.util.Date date1 = (java.util.Date)formatnow.parse(date);
String date2 = formatneeded.format(date1);
java.util.Date date3= (java.util.Date)formatneeded.parse(date2);
java.sql.Date sqlDate = new java.sql.Date( date3.getTime() );
pst.setDate(1, sqlDate);
LocalDate date4 = ZonedDateTime
.parse(date, DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH))
.toLocalDate();
java.sql.Date date5 = java.sql.Date.valueOf(date4);
I am using the modern classes in the java.time package. You notice that the code is not only simpler, once you get acquainted with the fluent writing style of the newer classes, it is also clearer.
If you wanted to be 100 % modern, you should also check out whether your latest MySQL JDBC driver wouldn’t accept a LocalDate directly without conversion to java.sql.Date. It should.
A few details to note
If you need your code to run on computers outside your control, always give locale to your formatter, or your date string cannot be parsed on a computer with a non-English-speaking locale. You may use Locale.ROOT for a locale neutral locale (it speaks English).
If you can, avoid the three letter time zone abbreviations. Many are ambiguous. EET is really only half a time zone since some places where it’s used are on EEST (summer time) now. Better to use either a long time zone ID like Europe/Bucharest or an offset from UTC like +02:00.
These points are valid no matter if you use DateTimeFormatter or SimpleDateFormat.
If you cannot or do not want to move on to the recommended newer classes, the fix to your code is:
SimpleDateFormat formatnow
= new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
SimpleDateFormat formatneeded = new SimpleDateFormat("yyyy-MM-dd");
I am using lowercase zzz since this is documented to match a three-letter time zone name, I know that uppercase ZZZ works too. I have added locale. And maybe most importantly, in the needed format I have changed YYYY (week-based year) to yyyy (calendar year) and DD (day of year) to dd (day of month). All those letters are in the documentation.
I know this question is related to java.sql.Date but as additional information, if you want to convert the date into LocalDate then below code might help:
private LocalDate getLocalDate(String date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd hh:mm:ss Z yyyy", Locale.getDefault());
return LocalDate.parse(date, formatter);
}
And once you get the LocalDate, you can transform it to any format. As the question expects yyyy-MM-dd then just call toString() on LocalDate object.
LocalDate curr = LocalDate.now();
System.out.println(curr.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
System.out.println(curr.toString());
It will display the date like "2019-11-20".
Hope this helps to someone.

How to convert date strings from different TimeZones to Date object in one TimeZone

Im working on an RSS reader software. I get items with their pubDate (publish date) values as string, convert them to Date object, and put them to my DB. However, when I check my DB, I saw some interesting values such as the date of tomorrow.
I research this situation and found that it is about time zone value Z. For example when I get "Mon, 26 May 2014 21:24:29 -0500", it becomes "2014-05-27 05:24:29", the next day !
All I want is to get dates in any timezone and convert them to date in common timezone, such as my country's.
Here is my code :
public static String convert(String datestr) throws ParseException {
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return resultFormatter.format(date);
}
And I use the method like that :
System.out.println(convert("Mon, 26 May 2014 21:24:29 -0500"));
The output is : 2014-05-27 05:24:29
Any idea ?
Since you haven't set a time zone, it's using your system's default.
Set a specific IANA time zone.
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
resultFormatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
return resultFormatter.format(date);
Looks like you passed a Date with timezone, but given a wrong format. If you are passing timezone like "-0500" you should rather use:
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
Remember that the system will always display the date using the current, default timezone (TimeZone.getDefault()) unless you override it by:
resultFormatter.setTimeZone(...)
This is working as expected. The date is converted as per your system's timezone.
Check the UTC offset of your system and replace it in the sample date string and look at the output.
For e.g: India is UTC+5:30
String datestr="Mon, 26 May 2014 21:24:29 +0530";
output:
2014-05-26 21:24:29
Alternate solution
If you don't want to consider the timezone of the input date string then simply truncate this information and remove zzz from pattern as well as shown in below code:
String datestr = "Mon, 26 May 2014 21:24:29 -0530";
datestr = datestr.replaceAll("\\s[-+](\\d+)$", ""); // truncate the timezone info if not needed
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); // remove zzz from the pattern
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(resultFormatter.format(date));

Error parsing date string

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.

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.

Java:Date format conversion issue

I have a date of the format EEE MMM dd HH:mm:ss zzz yyyy
I have to convert this to dd/MM/yyyy
I did the following:
SimpleDateFormat fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
SimpleDateFormat fmtddMMyyyy = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date d = fmt.parse("Mon May 28 00:00:00 IST 2012");<br>
String formattedDate = fmtddMMyyyy.format(d);
When I tried to print d it displays 0027833001988071567.
Where am I going wrong?
I have to guess that your real code is only marginally connected to what you show. Due to some experiments and the documentation.
Possibly the original parsing throws an exception and what every you print has nothing to do with you date manipulation.
In order to fix the problem
print the string you want to convert
print the parsed date
print the converted String
Use the constructor variants with Locale argument so everybody on stackoverflow can reproduce it, and you application works the same wherever it is running.
All this in a simple class containing nothing but a main method which contains the code.
If the problem persists, come back with the code and its output.
With my advice partially applied you might end with this:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class Experiment {
public static void main(String args[]) throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
SimpleDateFormat fmtddMMyyyy = new SimpleDateFormat("dd/MM/yyyy",
Locale.US);
java.util.Date d = fmt.parse("Mon May 28 00:00:00 IST 2012");
String formattedDate = fmtddMMyyyy.format(d);
System.out.println(formattedDate);
}
}
Which prints out
28/05/2012
try:
String formattedDate = fmtddMMyyyy.format(d);
UPD: Well I got the following solution:
SimpleDateFormat fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
works fine (without locale defining wasn't working for me too). Because you define the month name and day-of-week name according to English language, not your local, as I presume.

Categories

Resources