Different values when parsing date [duplicate] - java

This question already has answers here:
Java string to date conversion
(17 answers)
Closed 6 years ago.
I am trying to parse this date with SimpleDateFormat and it is not working:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Formaterclass {
public static void main(String[] args) throws ParseException{
String strDate = "Thu Jun 18 20:56:02 EDT 2009";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date dateStr = formatter.parse(strDate);
String formattedDate = formatter.format(dateStr);
System.out.println("yyyy-MM-dd date is ==>"+formattedDate);
Date date1 = formatter.parse(formattedDate);
formatter = new SimpleDateFormat("dd-MMM-yyyy");
formattedDate = formatter.format(date1);
System.out.println("dd-MMM-yyyy date is ==>"+formattedDate);
}
}
If I try this code with strDate="2008-10-14", I have a positive answer. What's the problem? How can I parse this format?
PS. I got this date from a jDatePicker and there is no instruction on how modify the date format I get when the user chooses a date.

You cannot expect to parse a date with a SimpleDateFormat that is set up with a different format.
To parse your "Thu Jun 18 20:56:02 EDT 2009" date string you need a SimpleDateFormat like this (roughly):
SimpleDateFormat parser=new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Use this to parse the string into a Date, and then your other SimpleDateFormat to turn that Date into the format you want.
String input = "Thu Jun 18 20:56:02 EDT 2009";
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Date date = parser.parse(input);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(date);
...
JavaDoc: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

The problem is that you have a date formatted like this:
Thu Jun 18 20:56:02 EDT 2009
But are using a SimpleDateFormat that is:
yyyy-MM-dd
The two formats don't agree. You need to construct a SimpleDateFormat that matches the layout of the string you're trying to parse into a Date. Lining things up to make it easy to see, you want a SimpleDateFormat like this:
EEE MMM dd HH:mm:ss zzz yyyy
Thu Jun 18 20:56:02 EDT 2009
Check the JavaDoc page I linked to and see how the characters are used.

We now have a more modern way to do this work.
java.time
The java.time framework is bundled with Java 8 and later. See Tutorial. These new classes are inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project. They are a vast improvement over the troublesome old classes, java.util.Date/.Calendar et al.
Note that the 3-4 letter codes like EDT are neither standardized nor unique. Avoid them whenever possible. Learn to use ISO 8601 standard formats instead. The java.time framework may take a stab at translating, but many of the commonly used codes have duplicate values.
By the way, note how java.time by default generates strings using the ISO 8601 formats but extended by appending the name of the time zone in brackets.
String input = "Thu Jun 18 20:56:02 EDT 2009";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE MMM d HH:mm:ss zzz yyyy" , Locale.ENGLISH );
ZonedDateTime zdt = formatter.parse ( input , ZonedDateTime :: from );
Dump to console.
System.out.println ( "zdt : " + zdt );
When run.
zdt : 2009-06-18T20:56:02-04:00[America/New_York]
Adjust Time Zone
For fun let's adjust to the India time zone.
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant ( ZoneId.of ( "Asia/Kolkata" ) );
zdtKolkata : 2009-06-19T06:26:02+05:30[Asia/Kolkata]
Convert to j.u.Date
If you really need a java.util.Date object for use with classes not yet updated to the java.time types, convert. Note that you are losing the assigned time zone, but have the same moment automatically adjusted to UTC.
java.util.Date date = java.util.Date.from( zdt.toInstant() );

How about getSelectedDate? Anyway, specifically on your code question, the problem is with this line:
new SimpleDateFormat("yyyy-MM-dd");
The string that goes in the constructor has to match the format of the date. The documentation for how to do that is here. Looks like you need something close to "EEE MMM d HH:mm:ss zzz yyyy"

In response to:
"How to convert Tue Sep 13 2016 00:00:00 GMT-0500 (Hora de verano central (México)) to dd-MM-yy in Java?", it was marked how duplicate
Try this:
With java.util.Date, java.text.SimpleDateFormat, it's a simple solution.
public static void main(String[] args) throws ParseException {
String fecha = "Tue Sep 13 2016 00:00:00 GMT-0500 (Hora de verano central (México))";
Date f = new Date(fecha);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("-5GMT"));
fecha = sdf.format(f);
System.out.println(fecha);
}

Related

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

Joda date formatter

Does anyone know how to parse a date such as: Mon Aug 04 16:07:00 CEST 2014
to dd/MM/YYYY HH:MM:SS using DateTime formatter from Joda.
I've tried that:
final DateTimeFormatter sdf = DateTimeFormat.forPattern(DATE_FORMAT);
DateTime lastDateOnline = sdf.parseDateTime(lastCommunicationToDisplay.getDateOnLine().toString());
return lastDateOnline.toString();
DATE_FORMAT = dd/MM/YYYY HH:MM:SS and
lastCommunicationToDisplay.getDateOnLine().toString() = Mon Aug 04 16:07:00 CEST 2014
I can't find clear explanations about that library. I'm requested to use that instead of SimpleDateFormat because it's not threadsafe.
Solutions
If all you have to do is convert a LocalDate to a string respecting the pattern: "dd/MM/YYYY HH:mm:ss", then you can do it in a simpler way, using the overloaded toString() methods on LocalDate:
a) the one which receives the format string directly:
LocalDate date = lastCommunicationToDisplay.getDateOnLine();
System.out.println(date.toString("dd/MM/YYYY HH:mm:ss"));
b) the one which receives a DateTimeFormatter initialized with the aforementioned string:
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/YYYY HH:mm:ss");
LocalDate date = lastCommunicationToDisplay.getDateOnLine();
System.out.println(date.toString(dtf));
What went wrong in your code
The format string you are using is not compatible with the date string you are sending as input. The way you used DateTimeFormatter is used for parsing strings that are in that format to LocalDates, not the other way around.
The format would be appropriate if your input string would look like the following:
04/08/2014 22:44:33
Since yours looks differently, the following value of the format is compatible (provided your timezone is always CEST):
DATE_FORMAT = "E MMM dd HH:mm:ss 'CEST' YYYY";
So the entire code should look like this:
String dateString = "Mon Aug 04 16:07:00 CEST 2014";
DateTimeFormatter dtf = DateTimeFormat.forPattern("E MMM dd HH:mm:ss 'CEST' YYYY");
LocalDate date = dtf.parseLocalDate(dateString);
System.out.println(date.toString("MM/dd/yyyy")); // or use toString(DateTimeFormatter) and use your pattern with a small adjusment here (dd/MM/YYYY HH:mm:ss)
However, I recommend one of the first 2 suggestions.

Convert String To Date BRT

I'm trying convert a String to Date, but I haven't gotten it.
My String is in the format:
"Fri Jun 13 10:24:01 BRT 2014"
I have Googled and found this resolution, but still continue catching an Exception.
Here is my code:
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("EEE MMM dd HH:mm:ss 'BRT' yyyy", Locale.getDefault());
df.setTimeZone(TimeZone.getTimeZone("BRT"));
try {
return df.parse(dateString);
} catch (Exception e) {
return null;
}
You need:
SimpleDateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("BRT"));
DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = df.parse("Fri Jun 13 10:24:01 BRT 2014");
System.out.println(utcFormat.format(d)); // output: 2014-06-13T12:24:01+0200
Consider following corrections:
Locale.ENGLISH instead of Locale.getDefault() enables reliable parsing of english names like "Jun" or "Fri"
Use pattern symbol z instead of literal 'BRT' because else the parser cannot interprete the string "BRT" as an abbreviation of a timezone name that is interpreting as Brazil Standard Time (in your case just parsing as literal hence not taking in account the timezone offset of UTC-03:00).
The answer by Meno Hochschild is correct. Pay attention to those items (1) & (2).
Joda-Time
FYI, using Joda-Time or java.time (new package in Java 8) is recommended over the notoriously troublesome java.util.Date and .Calendar classes.
Example in Joda-Time 2.3.
String input = "Fri Jun 13 10:24:01 BRT 2014";
Via a Locale object, specify the language by which to interpret the day-of-week and month names during the parsing.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss z yyyy" ).withLocale( Locale.ENGLISH );
Rather than rely on the default, specify a time zone to assign to the fresh DateTime object resulting from the parsing. Unlike a java.util.Date object, a DateTime truly knows its own assigned time zone.
DateTimeZone timeZone = DateTimeZone.forID( "America/Sao_Paulo" ); // Arbitrary choice of example time zone.
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
Usually you should be working in Universal Time (UTC). Easy to convert.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Built-in formatter is based on ISO 8601 format.
String output = dateTime.toString();
Or define your own pattern, or use one of the other pre-defined formats.
String outputInAwkwardFormat = formatter.print( dateTime );

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.

Categories

Resources