Java.text.ParseException: Unbeatable Date

I get the following error: 'java.text.ParseException: Unmatched date: "Aug 31, 09:53:19 2011" in this format: new SimpleDateFormat("MMM dd HH:mm:ss yyyy");

Does anyone see a problem?

+7
source share
3 answers

Make sure you use the correct language. (The SimpleDateFormat(String) constructor uses the standard locale of the system , which may not be the one you want to use.)

This works fine on my machine:

 String input = "Aug 31 09:53:19 2011"; DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US); System.out.println(df.parseObject(input)); 

(When using Locale.FRENCH , for example, the result is in ParseException .)

+22
source

The format for input is entered. But you can get this error if your locale defaults to something where "Aug" is not a valid month name abbreviation. Try using, for example, Locale.US , and you will see that it will work:

 DateFormat df = new SimpleDateFormat("MMM dd HH:mm:ss yyyy", Locale.US); Date date = df.parse("Aug 31 09:53:19 2011"); 
+4
source

TL; DR

 LocalDateTime ldt = LocalDateTime.parse( "Aug 31 09:53:19 2011" , DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss yyyy" ).withLocale( Locale.US ) ) ; 

More details

The other two answers by aioobe and from Jesper are correct: implicitly use Locale with a human language that does not match the language of your input text.

This answer explains a new way to complete a task. In addition, other answers do not address the critical issue of the time zone.

java.time

Speed ​​things up a few years later from this publication, and now we have the new java.time package built into Java 8 and later. These new classes replace the old java.util.Date/.Calendar and SimpleDateFormat classes. Those old classes were troublesome, confusing and vicious.

Formatting pattern

Define the analyzed data and their format.

 String input = "Aug 31 09:53:19 2011"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss uuuu" ); 

If not specified, DateTimeFormatter is assigned by Locale , which is the default in the JVM. This default value can change at any time, even at runtime (!). Therefore, always indicate the desired / expected Locale .

 formatter = formatter.withLocale( Locale.US ); // Or Locale.UK, Locale.CANADA_FRENCH, etc. 

Given that there is no time zone or offset-from- UTC at the input, analyze as LocalDateTime .

 LocalDateTime ldt = LocalDateTime.parse( input , formatter ); 

If you know the estimated UTC-offset or timezone for this date-time value from the context, assign it.

If UTC, use the ZoneOffset.UTC constant to get the OffsetDateTime object.

 OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ); 

The time zone is UTC-offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Use the correct time zone names , never 3-4 letter abbreviations .

 ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = ldt.atZone( zoneId_Montreal ); 

Specify time zone

This element of human language has been a key missing element to answer the question. Specifying the correct Locale for the human language that matches the language of your input string solves this problem.

But note that the time zone is also critical; other answers ignored this problem, thereby implicitly using the current JVM default time zone. This is impractical since it depends on the host operating system as the initial default value (therefore, it can vary), and in addition, any code in any thread of any application in the JVM can change the current time zone of JVMs by default at runtime. It is better to specify the desired / expected time zone than rely implicitly on the default value.

Immutable objects

Pay attention to the syntax. These classes are intended to be immutable . Therefore, instead of changing (mutating) an object, a new new object is created based on the values ​​of the old objects. This means that we do not affect the DateTimeFormatter object defined above, and hold it in the formatter variable (object reference). We create, use and discard a new DateTimeFormatter object (in fact, two new objects) inside this line of code.

Method reference

The documentation suggests an alternative way to parse a string - call the parse method, in which you pass the method reference (new in Java 8) from the class of the desired result (like TemporalQuery ): ZonedDateTime::from , LocalDateTime::from , LocalDate::from , etc. d.

 ZonedDateTime zdt = formatter.withZone( zoneId_Montreal ).withLocale( Locale.ENGLISH ).parse( input, ZonedDateTime :: from ); 

To demonstrate, turn around and create a string representation of this ZonedDateTime value, but in Québécois French.

 String output = formatter.withLocale( Locale.CANADA_FRENCH ).format( zdt ); 

Even better, it allows you to localize, rather than hard-code, a specific format.

 String outputLocalized = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ).format( zdt ); 

Dump for the console.

 System.out.println( "input: " + input ); System.out.println( "formatter: " + formatter ); System.out.println( "zdt: " + zdt ); System.out.println( "output: " + output ); System.out.println( "outputLocalized: " + outputLocalized ); 

At startup.

 input: Aug 31 09:53:19 2011 formatter: Text(MonthOfYear,SHORT)' 'Value(DayOfMonth,2)' 'Value(HourOfDay,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)' 'Value(YearOfEra,4,19,EXCEEDS_PAD) zdt: 2011-08-31T09:53:19-04:00[America/Montreal] output: août 31 09:53:19 2011 outputLocalized: mercredi 31 août 2011 9 h 53 EDT 

About java.time

The java.time framework is built into Java 8 and later. These classes supersede old nasty time classes such as java.util.Date , .Calendar and java.text.SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises switching to java.time.

To learn more, see the Oracle Tutorial . And search for qaru for many examples and explanations.

Most java.time functions return to Java 6 and 7 in ThreeTen-Backport and then adapt to Android in ThreeTenABP .

The ThreeTen-Extra project extends java.time with additional classes. This project is a proof of possible future additions to java.time.

+2
source

All Articles