简体   繁体   中英

Calendar class in Java, ParseException

So, I'm experimenting with the Calendar class in Java, and I'm writing a method which returns a Calendar object.

What I want for said method is to return a Calendar object containing "Sun Feb 09 22:49:36 +0000 2014" .

Now I'm (debatably) not lazy and I have done some work on my method.

    Calendar cal = Calendar.getInstance();

    SimpleDateFormat sdf = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss Z yyyy");
    try {
        cal.setTime(sdf.parse("Sun Feb 09 22:49:36 +0000 2014"));
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return cal;

The problem is it keeps telling me that I got a ParseException , that it's an "Unparseable date" .

I thought my logic was pretty correct, but I'm starting to doubt it.

I'd prefer it without importing any more than Calendar , but SimpleDateFormat seems to be pretty handy too.

The less imports the better, I always say.

Anyone see how what I want can be achieved?

EDIT 1

Tried to run the code in a main method and just print out the result, with no difference in Exception.

The following is my main:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;


public class TestingMyCalendar {

public static void main(String[] args) {

    Calendar cal = Calendar.getInstance();

    SimpleDateFormat sdf = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss Z yyyy");
    try {
        cal.setTime(sdf.parse("Sun Feb 09 22:49:36 +0000 2014"));
    } catch (ParseException e) {
        e.printStackTrace();
    }

    System.out.println(cal);

}
}

For those interested, the following is my entire console text after the main crashed:

java.text.ParseException: Unparseable date: "Sun Feb 09 22:49:36 +0000 2014"
at java.text.DateFormat.parse(Unknown Source)
at TestingMyCalendar.main(TestingMyCalendar.java:15)
java.util.GregorianCalendar[time=1391987659892,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2014,MONTH=1,WEEK_OF_YEAR=7,WEEK_OF_MONTH=2,DAY_OF_MONTH=10,DAY_OF_YEAR=41,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=14,SECOND=19,MILLISECOND=892,ZONE_OFFSET=3600000,DST_OFFSET=0]

You may need to set your default locale to Locale.ENGLISH , otherwise the parser might choke on the Sun for Sunday.

Try:

Locale.setDefault(Locale.ENGLISH);

Or, specify it as part of the constructor call:

SimpleDateFormat sdf = new SimpleDateFormat(
        "EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);

Your stacktrace indicates Europe/Berlin as the timezone suggests that you are using a German Locale . The day or month fields may not match those from your default locale, Try

SimpleDateFormat sdf = 
          new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);

The other answers are correct. I'll add a few thoughts.

Defaults Are Tricky

Probably the most common source of trouble in date-time work is inadvertently relying on:

I've come to the conclusion that both should be specified in all my code, as a habit. I don't want my code changing its behavior (or breaking, as in your case) if it happens to be run with a different time zone or locale setting.

The only case where date-time code should use the default is when you truly want to detect and utilize the user's (the JVM's) own settings for localization. And even in this case, I explicitly make a call to retrieve and use the default rather than rely on the implicit default, so as to make my code obvious and self-documenting.

Joda-Time

As a commenter said, minimizing your imports is indeed a queer goal. Especially with java.util.Calendar and java.util.Date – If ever there were a case for imports it would be those two classes. They are notoriously troublesome, and should be avoided. Use Joda-Time . Or, in Java 8, use the bundled new java.time.* package , inspired by Joda-Time, defined by JSR 310 .

Note that in Joda-Time, a DateTime object truly knows its own assigned time zone. That's a big contrast to java.util.Date which has no assigned time zone but its toString applies the JVM's default time zone which leads to much confusion.

Here is some example code in Joda-Time 2.3.

String input = "Sun Feb 09 22:49:36 +0000 2014";

DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss Z yyyy" ).withLocale( Locale.ENGLISH ).withZone( timeZone );
DateTime dateTime = formatter.parseDateTime( input );

Dump to console…

System.out.println( "dateTime: " + dateTime );
System.out.println( "Same dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );

When run…

dateTime: 2014-02-09T17:49:36.000-05:00
Same dateTime in UTC/GMT: 2014-02-09T22:49:36.000Z

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM