I have a String that represents a date in French locale : 09-oct-08 :
I need to parse that String so I came up with this SimpleDateFormat :
String format2 = "dd-MMM-yy";
But I have a problem with the month part, that seems to be expected with a ending dot :
df2.format(new Date());
gives me :
28-oct.-09
What is now the best way for me to make SimpleDateFormat understand ("09-oct-08") ?
Full Code :
String format2 = "dd-MMM-yy";
DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH);
date = df2.parse("09-oct-08");
This gives me : java.text.ParseException: Unparseable date: "09-oct-08"
And if I then try to log :
df2.format(new Date());
I get : 28-oct.-09
Ok, then try «brute force» :)
Outputs
28-Oct-09
I don't see any dots sir. Have you tried re-checking your prints? Maybe you accidentally placed a
.
beside yourMMM
?You're getting
java.text.ParseException: Unparseable date: "09-oct-08"
since"09-oct-08"
does not match the formatting ofLocale.FRENCH
either use the default locale(US I think) or add a.
beside youroct
java.time
Let’s see if the java.time framework can help.
About java.time
The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
LocalDate
Unlike the old classes, java.time offers the
LocalDate
class to represent a date-only value, with no time-of-day nor time zone.French Abbreviations
Take a look at what the formatters in java.time expect for abbreviated month names in en Français.
We can loop the
Month
enum to get a list of months. This enum offers thegetDisplayName
method for generating a localized name of the month. This code demonstrates that the method produces the same output as the java.time formatter.We find a mix of 3 and 4 letter spellings. Longer names are abbreviated to four characters plus a period (FULL STOP). Four months have names short enough to be used without abbreviation:
mars
,mai
,juin
,août
.So, as discussed in the other Answers, no simple solution.
Fix the Data Source
My first suggestion is to fix your data source. That source apparently fails to follow proper French rules for abbreviation. Yale agrees with Java 8’s understanding of French. By the way, if fixing your data source I strongly suggest using four-digit years as two lead to no end of confusion and ambiguity.
Fix the Input
Of course the source may be out of your control/influence. In that case, as with the other Answers, you may need to do a brute-force replace rather that attempt any cleverness. On the other hand, if the only problem with your input is simply missing the period (FULL STOP), then you could soft-code using the
Month
enum rather than hard-code the improper values.I would make an initial parse attempt. Trap for the
DateTimeParseException
, before attempting a fix. If the exception is thrown, then fix the input.To fix the input, try each month of the year by looping the possible set of enum instances. For each month, get its abbreviated name. Strip the period (FULL STOP) from that abbreviation, to match what we suspect is our improper incoming value. Test to see if that indeed is a match for the input. If not, go to next month.
When we do get a match, fix the input to be properly abbreviated for the Locale’s rules (French rules in our case). Then parse the fixed input. This would be our second parse attempt, as we made an initial attempt up top. If this second attempt fails, something is very wrong as noted in the
FIXME:
seen here. But normally this second parse attempt will succeed, and we can bail out of thefor
loop of theMonth
enum.Finally, you could verify success by testing if the result is still the bogus flag value set initially (
LocalDate.MIN
).Dump to console.
I was having the same problem (french and the extra dots) and I believe the right way to solve this problem is by globally overwriting the french locale like so:
The original
monthsShort
french object has the dots likejanv._févr._mars_avr._...
, so we're just removing them.Here's a link to docs where you can check what can be overwritten.
Note that we don't need to pass a complete locale object if we just want to overwrite ie.:
monthsShort
.You can simply remove the ".":
Edit, regarding the lemon answer:
It seems to be a problem with the formatting when using the Locale French. Thus, I suggest that you simply use the
.
removal as I explained.Indeed, the following code:
displays the following output:
Edit again
Ok, I got your problem right now.
I don't really know how you can solve this problem without processing your String first. The idea is to replace the month in the original String by a comprehensive month:
I agree, this is awful, but I don't see any other solution if you use to
SimpleDateFormat
andDate
classes.Another solution is to use a real date and time library instead of the original JDK ones, such as Joda Time.
This seems to work:
Edit: Looks like St. Shadow beat me to it.