Parse a String to Date in Java - 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.

Related

java.text.ParseException: Unparseable date: "Wed Mar 11 2020"

The full date received from the request is of this format
Wed Mar 11 2020 05:29:01 GMT+0100 (West Africa Standard Time)
Now I substringed it to this - Wed Mar 11 2020
date.substring(0,15))
To enable me to save the date, I am parsing it as below
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd", Locale.ENGLISH);
Date parsedDate = null;
try {
parsedDate = format.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
When the code is ran, I get below error
java.text.ParseException: Unparseable date: "Wed Mar 11 2020"
I have also tried parsing with
SimpleDateFormat format = new SimpleDateFormat("EE MMM dd HH:mm:ss z yyyy",
Locale.ENGLISH);
based on SO answers and I am still getting date parsing error.
How can I parse this date - date.substring(0,15))
The format you need to match your date is EEE MMM dd yyyy e.g.
String date = "Wed Mar 11 2020 05:29:01 GMT+0100 (West Africa Standard Time)";
date = date.substring(0,15);
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd yyyy");
Date parsedDate = null;
try {
parsedDate = format.parse(date);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(parsedDate);
SimpleDateFormat outformat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(outformat.format(parsedDate));
Output:
Wed Mar 11 00:00:00 CET 2020
2020-03-11
Three points:
Do use java.time, the modern Java date and time API, for your date and time work.
Rather than taking a substring of the string you receive, I’d prefer to parse the entire string.
Your format pattern string must match the string you are trying to parse (and vice versa). Exactly.
In code:
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern(
"EEE MMM d uuuu HH:mm:ss 'GMT'xx (zzzz)", // Pattern to match your input strings.
Locale.UK // Locale determines human language used to parse name of month and such.
)
;
String dateString = "Wed Mar 11 2020 05:29:01 GMT+0100 (West Africa Standard Time)";
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateString, formatter);
Generate a string.
System.out.println( zonedDateTime.toString() );
Output from this snippet is:
2020-03-11T03:29:01+01:00[Africa/Lagos]
Use java.time. The modern API is sol much nicer to work with. The Date class that you used is poorly designed, and SimpleDateFormat notoriously troublesome. Don’t use any of those.
Parse the entire string. Taking a substring of length 15 will cause some readers of your code to wonder, some ask “WTF?”, some to use their precious time for counting to make sure that 15 is the correct length. Also taking a substring of length 15 is fragile unless you’re sure that the abbreviations for day of week and for month always have length three and day of month is always written with two digits (May 02, not May 2). Furthermore it’s easier to parse more than you need and throw information away later, than to parse just what you think you need and later discover that you needed one more bit.
Specifying the format. Since your string begins with a day of week abbreviation, you need a format pattern string that begins with the format pattern letter for day of week. In this case EEE (or E or EE) for the abbreviation (EEEE would have meant the day written in full, like Wednesday). So YYYY-MM-dd is all wrong. EE MMM dd HH:mm:ss z yyyy comes closer and can parse day of week, month and day of month. Then comes a space and a year in the input, but your format pattern string has yyyy for year at the end instead, so this is where parsing breaks for you. If writing the correct format pattern string teases (as it does for many), a trick is to try something and first use the formatter for formatting a date and time. If the result differs from the string we would like to parse, it usually gives us a hint about what’s wrong.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Try this.
SimpleDateFormat sdf3 = new SimpleDateFormat("EEE MMM dd yyyy");
Date d1 = null;
try {
d1 = sdf3.parse("Wed Mar 30 2016");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(sdf3.format(d1));
}
Output:
Wed Mar 30 2016
First you need to control your computer language. According to your computer's language. You must write day's name and month's name in your computer's language
Actually you had better convert this 'Wed' according to your language.
My computer's language is turkish.
I used below code how to use day's name on date on java.
public static void main(String[] args) {
String sDate1 = "Per Mar-11-2020";
String sDate2 = "Perşembe Mar-11-2020";
Date date1;
try {
date1 = new SimpleDateFormat("EEE MMM-dd-yyyy").parse(sDate1);
System.out.println(sDate1+"\t\t"+date1);
date1 = new SimpleDateFormat("EEEEE MMM-dd-yyyy").parse(sDate2);
System.out.println(sDate2+"\t\t"+date1);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
output :
Per Mar-11-2020 Wed Mar 11 00:00:00 AST 2020
Perşembe Mar-11-2020 Wed Mar 11 00:00:00 AST 2020
Also you need to be carefull such as :
if your String is Per Mar-11-2020, you need to write EEE MMM-dd-yyyy.
Or
if your String is Per Mar 11 2020, you need to write EEE MMM dd yyyy.
Or
if your String is Per Mar/11/2020, you need to write EEE MMM/dd/yyyy.

How to compare the datetime of format "EEE MMM dd HH:mm:ss zzz yyyy" and "yyyy-MM-dd hh:mm:sss" in java?

I have date of type "EEE MM DD HH:mm:ss zzz yyyy" (Wed Mar 04 03:34:45 GMT+08:00 2020) and "yyyy-MM-dd hh:mm:ss" (2020-02-04 02:10:58).How to compare this two date in java?
Both dates are in same timezone.
If you assume that the timezone of the second date is the same as for the first one then you can just use java.time. It has all parsing tools you need. Any other fixed timezone works as well.
Here is an example:
String a = "Wed Mar 04 03:34:45 GMT+08:00 2020";
String b = "2020-02-04 02:10:58";
ZonedDateTime parsedA;
ZonedDateTime parsedB;
DateTimeFormatter formatterA = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy");
parsedA = ZonedDateTime.parse(a, formatterA);
DateTimeFormatter formatterB = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
parsedB = LocalDateTime.parse(b, formatterB).atZone(parsedA.getZone());
// What do you want to compare? For example you can tell if a is after b.
System.out.println(parsedA.isAfter(parsedB));
Have a look here if you need another format and need a listing of Pattern Letters and Symbols.
First of all these two dates are not comparable because of missing timezone in the second date.
Secondly, If you still want to do that with system's default time zone then you need to bring both the dates into common format.
Parse the dates into Date object and then you can play around it:
DateFormat dateFormat1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
Date date1 = dateFormat1.parse("Wed Mar 04 03:34:45 GMT+08:00 2020");
DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date2 = dateFormat2.parse("2020-02-04 02:10:58");
System.out.println(date1.after(date2));
There is a difference between time zone and time zone offset. The Date-Time string Wed Mar 04 03:34:45 GMT+08:00 2020 has a time zone offset, not a time zone. A time zone is unique and therefore it has an ID e.g. ZoneId.of("America/New_York") whereas a time zone offset tells you about the amount of time by which a given time is offset from the UTC time. There can be many time zones falling on the same time zone offset. Check List of tz database time zones to learn more about it. So, the most appropriate type to parse Wed Mar 04 03:34:45 GMT+08:00 2020 into is OffsetDateTime.
Since the second Date-Time string 2020-02-04 02:10:58 has neither a time zone nor a time zone offset, parse it into LocalDateTime.
Make sure to use Locale with the formatter because Date-Time parsing/formatting API is Locale-sensitive.
As long as the second Date-Time string refers to a Date-Time at the same timezone offset (i.e. GMT+08:00), you can do either of the two to compare them
Convert the first Date-Time string into LocalDateTime after parsing and then compare it with the second Date-Time string parsed into a LocalDateTime.
Convert the second Date-Time string into an OffsetDateTime after parsing and then compare it with the first Date-Time string parsed into an OffsetDateTime.
I would prefer the first approach as it is simpler. However, for the sake of completeness, I've shown below both approaches.
First approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
LocalDateTime firstLocalDateTime = firstOffsetDateTime.toLocalDateTime();
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
// Compare the two LocalDateTime values using isBefore, isAfter, equals etc.
if (firstLocalDateTime.isBefore(secondLocalDateTime)) {
// ...
}
Second approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
OffsetDateTime secondOffsetDateTime = secondLocalDateTime.atOffset(firstOffsetDateTime.getOffset());
// Compare the two OffsetDateTime values using isBefore, isAfter, equals etc.
if (firstOffsetDateTime.isBefore(secondOffsetDateTime)) {
// ...
}
I also prefer u to y with a DateTimeFormatter.
Learn more about the the modern date-time API from Trail: Date Time.

Using SimpleDateFormat to format a string parse exception? [duplicate]

This question already has answers here:
String to Date Conversion mm/dd/yy to YYYY-MM-DD in java [duplicate]
(5 answers)
Closed 4 years ago.
I have a date object that returns the below string value in doing date.toString()
String date = "Wed Jun 27 12:33:00 CDT 2018";
And I want to format it in exactly this style:
"June-27-2018 5:33:00 PM GMT".
I tried using SimpleDateFormat
protected SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
But I keep getting a parse exception. Is there any way to format this the way I need it to? The timezone needs to be converted too.
First, you shouldn’t have a Date object. The Date class is long outdated (no pun intended). Today you should prefer to use java.time, the modern and much nicer date and time API. However, I am assuming that you are getting a Date from some legacy API that you cannot change. The first thing you should do is convert it to an Instant. Instant is the corresponding class in java.time. Then you should do any further operations from there.
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("MMMM-dd-yyyy h:mm:ss a z", Locale.US);
ZoneId desireedZone = ZoneId.of("Etc/GMT");
Date yourOldfashionedDate = // …;
ZonedDateTime dateTimeInGmt = yourOldfashionedDate.toInstant().atZone(desireedZone);
String formattedDateTime = dateTimeInGmt.format(formatter);
System.out.println(formattedDateTime);
This snippet prints the desired:
June-27-2018 5:33:00 PM GMT
Converting directly from the Date object is safer and easier than converting from its string representation. The biggest problem with the latter is that the string contains CDT as time zone, which is ambiguous. It may stand for Australian Central Daylight Time, North American Central Daylight Time, Cuba Daylight Time or Chatham Daylight Time. You cannot be sure which one Java is giving you. Never rely on three and four letter time zone abbreviations if there is any way you can avoid it.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Your date string cannot parse to the format you have given, so change the format to EEE MMM dd HH:mm:ss zzz yyyy
String myDate = "Wed Jun 27 12:33:00 CDT 2018";
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
SimpleDateFormat dateFormat_2 = new SimpleDateFormat("MMMM-dd-yyyy h:mm:ss a z", Locale.US);
dateFormat_2.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d = dateFormat.parse(myDate);
dateFormat_2.format(d);
System.out.println(dateFormat_2.format(d));
Output :
June-27-2018 12:33:00 PM GMT
You will achieve your desired output if you pass date or object to format function.
SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
String ans=dateFormat.format(param);
In above code param must be date or object so first convert string to date and then apply format function to get your desired output.
See below Sample code
SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String ans=dateFormat.format(new Date());
Sample output:
June-27-2018 6:22:35 PM GMT

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.

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