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.
Related
I want to convert a date to GMT.
I get a date in BST, I want to convert it to GMT without time zone conversion.
Example:
**If the BST date is: Wed June 26 13:30:13 BST 2019
I want to convert it to Wed 26 Jun 2019 13:30:13 GMT**
I want to ignore the timezone info and return the same date as GMT.
For this I am trying
private SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private SimpleDateFormat dateFormatGmtText = new SimpleDateFormat("EEE dd MMM yyyy HH:mm:ss 'GMT'");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String textDate = dateFormatLocal.format(date);
//Date is Wed June 26 13:30:13 BST 2019
private Date toGMTDate(final Date date) {
String textDate = dateFormatLocal.format(date);
try {
String[] dateParts = textDate.split("\\+");
textDate = dateParts[0] + "+0000";
return dateFormatGmt.parse(textDate);
} catch (ParseException e) {
return null;
}
}
private String toGMT(final Date date) {
return dateFormatGmtText.format(toGMTDate(date));
}
When I call toGMT it returns Wed 26 Jun 2019 14:30:13 GMT
I am not sure why it is so?
What is wrong here?
java.time
You said you can’t use the modern date and time API, but for other readers I should like to present that option first. SimpleDateFormat and Date are poorly designed and long outdated, the former in particular notoriously troublesome, so I recommend avoiding them.
I am assuming that BST is for British Summer Time (other interpretations exist). And I am assuming that you cannot avoid getting an old-fashioned Date object.
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEE dd MMM yyyy HH:mm:ss z", Locale.UK);
private static ZoneId britain = ZoneId.of("Europe/London");
private static ZoneId gmt = ZoneId.of("Etc/GMT");
private static String toGMT(final Date date) {
ZonedDateTime britishTime = date.toInstant().atZone(britain);
ZonedDateTime gmtTime = britishTime.withZoneSameLocal(gmt);
return gmtTime.format(formatter);
}
Try it out with your Date of Wed Jun 26 13:30:13 BST 2019:
String textDate = dateFormatLocal.format(date);
System.out.println(textDate);
System.out.println(toGMT(date));
Output is:
2019-06-26T13:30:13+0100
Wed 26 Jun 2019 13:30:13 GMT
Whenever you get an old-fashioned Date, the first thing to do is to convert it to Instant. Then do any further conversions from there. The key to changing time zone and keeping the date and time of day (hour-minute-second of day) is the withZoneSameLocal method of the ZonedDateTime class.
I recommend specifying locale for the formatter.
I am not sure why it is so? What is wrong here?
A Date hasn’t got, as in cannot have a time zone. It’s a point in time, nothing more. YourtoGMTDate method returns a point in time that is an hour later: The time you gave it was 13:30:13+0100, and it returned 13:30:13+0000, which is the same point in time as 14:30:13+0100. Next you formatted this point in time using a formatter that used your default time zone, Europe/London, and therefore produced 14:30:13, but at the same time printed GMT in the string — the result you reported.
…the new time library, but for some reasons I can't use them.
If you really have got an evil boss that either forces you to use Java 1.4 or 1.5 and/or forbids the use external dependencies, the pretty simple hack is:
private String toGMT(final Date date) {
return dateFormatGmtText.format(date);
}
The cheating is: Your dateFormatGmtText uses your default time zone, Europe/London, but lies and prints GMT in the formatted string. This gives the same output as above — the output you asked for. Compared to your code I am just leaving out the date conversion.
Link: Oracle tutorial: Date Time explaining how to use java.time.
This question already has answers here:
How to convert date in to yyyy-MM-dd Format?
(6 answers)
How can I convert Date.toString back to Date?
(5 answers)
Java - Unparseable date
(3 answers)
Closed 5 years ago.
I got problem with date parse example date:
SimpleDateFormat parserSDF=new SimpleDateFormat("EEE MMM dd HH:mm:ss zzzz yyyy", Locale.getDefault());
parserSDF.parse("Wed Oct 16 00:00:00 CEST 2013");
got exception
Exacly I want parse this format date to yyyy-MM-dd
I try:
SimpleDateFormat parserSDF = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date date = parserSDF.parse("Wed Oct 16 00:00:00 CEST 2013");
take :
java.text.ParseException: Unparseable date: "Wed Oct 16 00:00:00 CEST 2013"
OK I change to and works :
SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzzz yyyy", Locale.ENGLISH);
Date date = parserSDF.parse("Wed Oct 16 00:00:00 CEST 2013");
I'm going to assume that Locale.getDefault() for you is pl-PL since you seem to be in Poland.
English words in date strings therefore cause an unparseable date.
An appropriate Polish date String would be something like
"Wt paź 16 00:00:00 -0500 2013"
Otherwise, change your Locale to Locale.ENGLISH so that the SimpleDateFormat object can parse String dates with English words.
Instead of using Locale.default that you and others often don't know which default, you can decide by using locale.ENGLISH because I see your string date is format in English. If you are at other countries, the format will be different.
Here is my example code:
public static void main(String[] args) {
try {
SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
Date date = parserSDF.parse("Wed Oct 16 00:00:00 CEST 2013");
System.out.println("date: " + date.toString());
} catch (ParseException ex) {
ex.printStackTrace();
}
}
The result will be : date: Wed Oct 16 05:00:00 ICT 2013. Or you can decide which part of this date to be printed, by using its fields.
Hope this help :)
I think the original Exception is due to Z in your format.
Per documentation:
Z Time zone RFC 822 time zone -0800
most likely you meant to use lower case z
I am trying to convert a String DateTime value which is present in a flat file as a Date object after parsing the flat file in my code.
I have written the code to do that but when I format the date its always giving me a date more than 1 day for the specified value, some times it's adding 5:30.
Below is the code for that:
DateFormat f = new SimpleDateFormat("EEE MMM dd HH:mm:ss zz yyyy");
Date date = f.parse("Tue Aug 23 20:00:03 PDT 2011");
System.out.println("---date----" + date);
The output for the above is
---date----Wed Aug 24 08:30:03 IST 2011
Can you please let me know whats the issue here. Is there a problem in the pattern that I am using in the SimplaDateFormat class or is there a problem with the code.
I have been scratching my head on this for a long time now.
Can you please let me know whats the issue here.
Sure. You're effectively calling date.toString(), which doesn't know anything about the SimpleDateFormat which was used to parse the original text value. A Date is just an instant in time. It has no notion of a per-instance format. Additionally, it doesn't know about a time zone. You've given a value in PDT, which was then parsed... and when you print it, it's using the system local time zone (IST). That's what Date.toString always does.
If you want to format a Date in a particular way, using a particular format in a particular time zone, call DateFormat.format.
Your system timezone is different. The output is showing IST - or Indian Standard Time, which is an 12.5h difference from PDT. The code is properly parsing the given date which is PDT (UTC -7) and printing out IST (UTC +5h30).
Java stores Dates as UTC dates. So when you parse the PDT date, Java will convert it to UTC and store it internally as a UTC timestamp. When you print, if you do not specify the timezone, it will default to the system timezone, which in your case would appear to be IST.
To specify an exact timezone, specify it in the SimpleDateFormat:
DateFormat f = new SimpleDateFormat("EEE MMM dd HH:mm:ss zz yyyy");
f.setTimeZone(TimeZone.getTimeZone("PDT"));
Date date = f.parse("Tue Aug 23 20:00:03 PDT 2011");
System.out.println("---date----" + f.format(date));
Because you are not formatting a date. Look at the example
public static void main(String[] args){
Locale currentLocale = Locale.US;
DateFormat f = new SimpleDateFormat("EEE MMM dd HH:mm:ss zz yyyy", currentLocale);
Date date = null;
Date today;
try {
today = new Date();
String result = f.format(today);
System.out.println("Locale: " + currentLocale.toString());
System.out.println("Result: " + result);
date = f.parse("Tue Aug 23 20:00:03 PDT 2011");
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("---date----" + f.format(date));
}
will output
Locale: en_US
Result: Tue Sep 25 19:12:38 EEST 2012
---date----Tue Aug 23 20:00:03 PDT 2011
Now, you have a bit modified code
public static void main(String[] args){
Locale currentLocale = Locale.US;
DateFormat f = new SimpleDateFormat("EEE MMM dd HH:mm:ss zz yyyy", currentLocale);
DateFormat f2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss zz yyyy", currentLocale);
Date date = null;
Date today;
try {
today = new Date();
String result = f.format(today);
System.out.println("Locale: " + currentLocale.toString());
System.out.println("Result: " + result);
date = f.parse("Tue Aug 23 20:00:03 PDT 2011");
System.out.println("---date----" + f.format(date));
System.out.println("---date----" + f2.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
which outputs to
Locale: en_US
Result: Tue Sep 25 20:42:10 EEST 2012
---date----Tue Aug 23 20:00:03 PDT 2011
---date----Wed Aug 24 06:00:03 EEST 2011
seems that SimpleDateFormat don't care about timezone even if 'z' pattern is specified. It is setting the timezone when it parses the input. That's how I can describe that a strange behavior. Then use of 'z' pattern seems obsolete and lead to unpredictable results.
so setting the TimeZone will fix the issue
f2.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
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.
I am using Joda to parse dates and have a format where leading zeros are not used, e.g.:
Mon Nov 20 14:40:36 2006
Mon Nov 6 14:40:36 2006
Note that the dayOfMonth field is left-padded with a blank.
Currently I seem to have to use two different formats and reparse if one fails
"EEE MMM dd HH:mm:ss yyyy"
"EEE MMM d HH:mm:ss yyyy"
Is there a single format (or an API switch) which deals with both cases? (is the answer the same for SimpleDateFormat - which I don't use?)
java.time and format pattern letter p
Here’s the modern answer, using java.time, the successor of Joda-Time.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM ppd HH:mm:ss uuuu", Locale.ENGLISH);
String[] stringsToParse = {
"Mon Nov 20 14:40:36 2006",
"Mon Nov 6 14:40:36 2006"
};
for (String dateTimeString : stringsToParse) {
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
}
Output:
2006-11-20T14:40:36
2006-11-06T14:40:36
To DateTimeFormatter.ofPattern format letter p means padding with spaces on the left. pp means padding to two position. It can be used for both formatting and — as here — parsing.
I know you asked about Joda-Time. The Joda-Time home page says:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of DateTimeFormatter
Joda-Time - Home
I have just created a quick program to check this -
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy");
try {
String source1 = "Mon Nov 20 14:40:36 2006";
Date d1 = sdf.parse(source1);
String source2 = "Mon Nov 6 14:40:36 2006";
Date d2 = sdf.parse(source2);
String res1 = sdf.format(d1);
String res2 = sdf.format(d2);
System.out.println(source1 +"="+ res1);
System.out.println(source2 +"="+ res2);
} catch (ParseException e) {
e.printStackTrace();
}
The output from this is -
Mon Nov 20 14:40:36 2006=Mon Nov 20 14:40:36 2006
Mon Nov 6 14:40:36 2006=Mon Nov 6 14:40:36 2006
So, even though source2 has the extra space, it is still parsed by
EEE MMM d HH:mm:ss yyyy
Hope that helps
I tried using a single 'd' as suggested above in logstash 1.1.1 but it still complained about a malformed date when a single digit day with an extra leading space was parsed. The following logstash rules did work.
timestamp => [ "MMM dd HH:mm:ss", "MMM d HH:mm:ss" ]
It didn't matter which order the two date formats were in. No more warnings were output once I added both formats.