BrunoMori
BrunoMori

Reputation: 21

SimpleDateFormat is parsing to a different Date

I'm trying to parse a String to a Date using SimpleDateFormat, but It generates a wrong value Date.

String dataNascimentoValue = "Thu Jan 01 00:00:00 GMT 1970";
SimpleDateFormat converter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");

Date date = new Date();

converter.setLenient(false);
date = converter.parse( dataNascimentoValue ); //at this moment It generates //a wrong Date: Wed Dec 31 19:00:00 EST 1969

SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String formatedDate = formatter.format( date );

I already tried to put a Locale at my SimpleDateFormat, but didn't work. I would like to parse the String to a Date, because I need to format It after.

Any help?

Screenshot of my try using the Locale.US

Upvotes: 1

Views: 1749

Answers (2)

Ruchika Sharma
Ruchika Sharma

Reputation: 708

you can use this method to parse string to date.

 private static final SimpleDateFormat _simpleDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

public static Date stringToJavaDateOnly(String dateStr)
            throws ParseException {
        return _simpleDateTimeFormat.parse(dateStr);
    }

Upvotes: 0

Basil Bourque
Basil Bourque

Reputation: 340118

tl;dr

ZonedDateTime.parse ( 
    "Thu Jan 01 00:00:00 GMT 1970" , 
    DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss zzz uuuu" , Locale.CANADA )                    
)

Feature, not a bug

These two strings:

  • Thur Jan 01 00:00:00 GMT 1970
  • Wed Dec 31 19:00:00 EST 1969

…represent the very same moment, the same point on the timeline. So no problem here; you are seeing correct behavior as documented.

The EST refers to the time zones used in the eastern portions of much of the United States and Canada. Such zones are five hours behind UTC (GMT). Midnight minus five hours is 7 PM (19:00) on the previous date. Different wall-clock time, but same moment in the history of the Universe.

One of the many poor design choices in the legacy date-time classes like Date is dynamically applying the JVM’s current default time zone during a call to toString generating a representation of a value that is otherwise always in UTC. Very confusing as this behavior creates the illusion of having a time zone when in fact the Date is always in UTC. Even more confusing, there actually is a time zone deep inside the Date used for some internal purposes but without any getter or setter for that zone. This class is an awful mess. Avoid it.

From your report I can deduce that your JVM has a current default time zone in EST.

Using java.time

You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes. Avoid these legacy classes; use only java.time classes.

Always specify a Locale when parsing date-time strings. If omitted, your JVM’s current default Locale is used in (a) determining the human language such as English for translating the text, and (b) determining the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.

String input = "Thu Jan 01 00:00:00 GMT 1970";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss zzz uuuu" , Locale.CANADA );
ZonedDateTime zdt = ZonedDateTime.parse ( input , f );

zdt.toString(): 1970-01-01T00:00Z[GMT]

You can adjust into other time zones. Apply a ZoneId to get another ZonedDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtMontreal = zdt.withZoneSameInstant( z );

zdtMontreal.toString(): 1969-12-31T19:00-05:00[America/Montreal]

The toString methods on java.time classes are more sensible and clear, using standard ISO 8601 formats when generating a textual representation of the date-time value.

See live code at IdeOne.com.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 3

Related Questions