views:

318

answers:

4

Hello,

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

+2  A: 

You can simply remove the ".":

df2.format(new Date()).replaceAll("\\.", ""));


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:

    String format2 = "dd-MMM-yy";
    Date date = Calendar.getInstance().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat(format2, Locale.FRENCH);
    System.out.println(sdf.format(date));
    sdf = new SimpleDateFormat(format2, Locale.ENGLISH);
    System.out.println(sdf.format(date));

displays the following output:

28-oct.-09
28-Oct-09


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:

        String[] givenMonths = { "jan", "fév", "mars", "avr.", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc" };
        String[] realMonths = { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." };
        String original = "09-oct-08";
        for (int i = 0; i < givenMonths.length; i++) {
            original = original.replaceAll(givenMonths[i], realMonths[i]);
        }
        String format2 = "dd-MMM-yy";
        DateFormat df2 = new SimpleDateFormat(format2, Locale.FRENCH);
        Date date = df2.parse(original);
        System.out.println("--> " + date);

I agree, this is awful, but I don't see any other solution if you use to SimpleDateFormat and Date classes.

Another solution is to use a real date and time library instead of the original JDK ones, such as Joda Time.

romaintaz
I though of this but I'm trying to do the reverse .... As my String does not have a dot and SimpleDateFormat seems to need it to parse the String ...Maybe I could add the dot to my input String but this don't appears to me to very "clean" coding ...
Jalil
I agree that it is not a good solution, but it seems to be a "bug" (?) in the SimpleDateFormat class with the French locale...
romaintaz
Please note that I'm not trying to **FORMAT** a Date as a String, but to **PARSE** an incoming String as a Date. So there is no dot in my incoming String, but SimpleDateFormat *needs* this dot to "understand" the month ...That is my problem.
Jalil
sdf = new SimpleDateFormat(format2, Locale.ENGLISH);System.out.println(sdf.parse("09-oct-08"));Will be ok.
St.Shadow
St. Shadow, as I said to Lemon, I cannot use the ENGLISH Locale because I'm receiving french date. While it's OK for October (Octobre in French), It would be problematic for February for exemple (I will receive 'fév' and not 'Feb').
Jalil
Ok, I got your problem now. I give you an awful solution to solve your problem. A better idea is to move to joda library!
romaintaz
If this is only one place, where we need new month names - no sence in third party libs. Just use givenMonths for DateFormatSymbols solve the problems.
St.Shadow
Yes I think these are the only 2 solutions. I'm not adding a new library for the single code ligne, but thank you for pointing it to me, I'll take a look. So for now, I think I'm gonna use the givenMonths->realMonths solution. Ugly but working.
Jalil
+2  A: 
String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2);
System.out.println(sdf.format(date));

Outputs 28-Oct-09

I don't see any dots sir. Have you tried re-checking your prints? Maybe you accidentally placed a . beside your MMM?


You're getting java.text.ParseException: Unparseable date: "09-oct-08" since "09-oct-08" does not match the formatting of Locale.FRENCH either use the default locale(US I think) or add a . beside your oct

lemon
And what about locale? Do you set French locale Locale.setDefault(Locale.FRANCE)?
St.Shadow
I just run your example, and I get the output `28-oct.-09`. Are you sure that you used the French locale? (I use Java 6)
romaintaz
As I said, this is because I'm working on French Locale ... Try with this : DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH);
Jalil
Romaintaz, my code is : 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
Jalil
Formatting in comments is awfull, I'm updating my main question.
Jalil
Lemon, I cannot use the US Locale because I'm receiving french date. While it's OK for October (Octobre in French), It would be problematic for February for exemple (I will receive 'fév' and not 'Feb').
Jalil
Okay, why not just adapt to the french locale version then? parse oct. instead of oct, that would eliminate the error.
lemon
Yes this is the only solution I can think of, adding the dot before the second "-". But first, it is not very pretty. And second, I fear the French locale does not have a dot for May for exemple, as the month is not shorten. I'm testing it right now.
Jalil
I confirm : java.text.ParseException: Unparseable date: "10-mai.-09" :-("10-mai-09" works OK. Yeah I know FRENCH locale sucks here :-)
Jalil
+1  A: 

Ok, then try «brute force» :)

DateFormatSymbols dfs = new DateFormatSymbols(Locale.FRENCH);
String[] months = new String[13]
<fill with correct month names or just replace these month, that are not fully correct>
dfs.setMonths(months);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", dfs);
Date nweDate = sdf.parse("09-fév-08");
St.Shadow
:-( This will not work with "02-mai-10" for 2 reasons : First, "Mai" is "May" in english. Second, "Mai" does not have the dot in FRENCH locale, as the month name in NOT shorten.
Jalil
"March", "June", "July" and "August" also are not "standardized" (they are "mars", "juin", "juil." and "août").
romaintaz
you can fill months array with any month names with/withot dots and so on. You can even fill with fake names: for example: month[0] = "dontknow". And it will parse sdf.parse("09-dontknow-08").
St.Shadow
I like the DateFormatSymbols solution ! I did not know this class, which direct use is not recommanded by the API :-(I can see that your months array is sized 13. Why not 12 ?
Jalil
Also I think I should rather use setShortMonths() method.
Jalil
13 - because origing dfs.getShortMonth() return array of size 13 - last is "" - look like for unrecognized month, but I don't take a look at it, so can not say exactly.
St.Shadow
Your right, for short month names you should use setShortMonths() method. setMonth() for full name (I think, you understand me :) )
St.Shadow
+1  A: 

This seems to work:

    DateFormatSymbols dfsFr = new DateFormatSymbols(Locale.FRENCH);
    String[] oldMonths = dfsFr.getShortMonths();
    String[] newMonths = new String[oldMonths.length];
    for (int i = 0, len = oldMonths.length; i < len; ++ i) {
        String oldMonth = oldMonths[i];

        if (oldMonth.endsWith(".")) {
            newMonths[i] = oldMonth.substring(0, oldMonths[i].length() - 1);
        } else {
            newMonths[i] = oldMonth;
        }
    }
    dfsFr.setShortMonths(newMonths);
    DateFormat dfFr = new SimpleDateFormat(
        "dd-MMM-yy", dfsFr);

    // English date parser for creating some test data.
    DateFormat dfEn = new SimpleDateFormat(
        "dd-MMM-yy", Locale.ENGLISH);
    System.out.println(dfFr.format(dfEn.parse("10-Oct-09")));
    System.out.println(dfFr.format(dfEn.parse("10-May-09")));
    System.out.println(dfFr.format(dfEn.parse("10-Feb-09")));

Edit: Looks like St. Shadow beat me to it.

Jack Leow
Yeeee... Don`t work for french: for french locale we will have "févr." as febryary and when you truncate it - we will have "févr" - and this can not parse "fév" (as author mentored at his question). Need maula set all 12 month with date, that need to be parsed.
St.Shadow
*If you will try to PARSE date, not to FORMAT
St.Shadow
This seems to me a very elegant solution ! But I don't understand why you use dfEn ? Why not just use the dfFr you've constructed to directly parse the String ? And St.Shadow, why would not this work ?
Jalil
Because I take a look at FRENCH shortMonthNames: they are [janv., févr., dontknow, avr., mai, juin, juil., août, sept., oct., nov., déc., ] - as you can see ferbryary here is "févr." and if you remove last dot - you will get "févr" and this is NOT "fév" and you can not parse string "fév" (as you mentored such name of febryary in your comments). If you will receive correct shormt month name, but only without dot - this solution will work good.
St.Shadow
for truncuting month I use «less letters»for (int i = 0; i < months.length; ++i) { months[i] = months[i].replaceFirst("\\.", "");}Do not check, is it more fast or not, but it shorter :))
St.Shadow
St.Shadow, I think your solution and romaintaz's are more flexible (allows for abbreviations that are different from how the JDK does it), I just did this to prove the concept. As for parsing vs formatting, I figure as long as the formatted output is correct, the parsing behavior should be the inverse of it, and should work too.
Jack Leow
Jalil, the purpose of dfEn is simply to parse and create test dates for testing dfFr (since I'm more familiar with the English behavior of SimpleDateFormat). I could have (and probably should have) just created the dates using GregorianCalendar, but didn't want to look that up. Hopefully this clear things up.
Jack Leow
St.Shadow, I'm sorry I confirm that the only problem was the dot and that I'm indeed receiving "févr". So this solution seems the most elegant to me ! Thanks all for all your time and propositions !
Jalil