Reputation: 1549
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]
Upvotes: 4
Views: 1666
Reputation: 338574
The other answers are correct. I'll add a few thoughts.
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.
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
Upvotes: 2
Reputation: 159774
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);
Upvotes: 2
Reputation: 41357
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);
Upvotes: 4