Reputation: 31493
I'm having a tough time parsing this date its the +0 at the end that is causing a problem, does anyone know whats wrong with my format string?? If I remove the +0 from the date string and the Z from the format string it works fine, unfortunately for my application that isn't an option.
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
SimpleDateFormat dateFormater = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss zZ");
try {
Date d = dateFormater.parse("Sun, 04 Dec 2011 18:40:22 GMT+0");
System.out.println(d.toLocaleString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Upvotes: 3
Views: 7640
Reputation: 338171
Use modern java.time classes.
OffsetDateTime
.parse (
"Sun, 04 Dec 2011 18:40:22 GMT+0" ,
DateTimeFormatter
.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )
.withLocale ( Locale.of ( "en" , "US" ) )
)
.toString ( )
Avoid the terribly-flawed legacy classes such as Calendar
, Date
, and SimpleDateFormat
. Use only the java.time classes in Java 8+.
Your input string "Sun, 04 Dec 2011 18:40:22 GMT+0"
seems to be a screwy version of the outmoded standard format defined in RFC 822 & RFC 1123. Java comes with a predefined formatter RFC_1123_DATE_TIME
for those standards, but your input varies a bit too much for that to work.
Tip: For storing and exchanging date-time values textually, use only ISO 8601 formats.
DateTimeFormatter
So we need to define our own pattern to match your input. Use DateTimeFormatter
class.
DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )
Locale
We need a Locale
to specify the human language and cultural norms to be used in translating the name of the month and name of the day-of-week.
Locale locale = Locale.of ( "en" , "US" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" ).withLocale ( locale );
OffsetDateTime
Parse as a OffsetDateTime
, to represent a moment as seen with an offset from the temporal meridian of UTC.
In this case the offset is zero hours-minutes-seconds from UTC. Shown below as Z
, pronounced “Zulu”.
String input = "Sun, 04 Dec 2011 18:40:22 GMT+0";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
Result:
odt.toString() = 2011-12-04T18:40:22Z
Upvotes: 1
Reputation: 183201
One approach is to use normal string-manipulation techniques to translate your string from a form that you're expecting to a form that SimpleDateFormat
will understand. You haven't said exactly what range of time-zone formats are acceptable, but one possibility is something like this:
private static Date parse(String dateString) throws ParseException
{
final SimpleDateFormat dateFormat =
new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss Z");
dateString = dateString.replaceAll("(GMT[+-])(\\d)$", "$1\\0$2");
dateString = dateString.replaceAll("(GMT[+-]\\d\\d)$", "$1:00");
return dateFormat.parse(dateString);
}
That would support GMT plus-or-minus a one-or-two-digit hour offset, in addition to still supporting anything already supported by SimpleDateFormat
, such as EST
or GMT+1030
.
Alternatively, if you know it will always be GMT, then you can just set the time-zone on the formatter, and ignore the time-zone in the string:
private static Date parse(String dateString) throws ParseException
{
final SimpleDateFormat dateFormat =
new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormat.parse(dateString);
}
You can also split the difference. I notice that the time-zone format in your string matches what's expected by TimeZone.getTimeZone()
. Is that intentional? If so, you can grab that time-zone format out of the string, pass it to dateFormat.setTimeZone
beforehand, and then ignore it during actual parsing:
private static Date parse(final String dateString) throws ParseException
{
final SimpleDateFormat dateFormat =
new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
if(dateString.indexOf("GMT") > 0)
dateFormat.setTimeZone
(
TimeZone.getTimeZone
(dateString.substring(dateString.indexOf("GMT")))
);
return dateFormat.parse(dateString);
}
Upvotes: 3
Reputation: 1108537
If the format is that consistent, you could append 0:00
to the date string.
String dateString = "Sun, 04 Dec 2011 18:40:22 GMT+0";
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss z", Locale.ENGLISH);
Date date = sdf.parse(dateString + "0:00");
System.out.println(date);
(note that I fixed the SimpleDateFormat
construction to explicitly specify the locale which would be used to parse the day of week and month names, otherwise it may fail on platforms which does not use English as default locale; I also wonder if you don't actually need HH
instead of kk
, but that aside)
Upvotes: 2