1

I got a Problem when converting a Date in my Android App. My Problem is that I got two different Formats of the Date.

SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
DateFormat formatter_date = new SimpleDateFormat("dd.MMM.yyyy");
Date myDate = null;
try {
    myDate = dateFormat.parse("28.10.2015");
} catch (ParseException e) {
    e.printStackTrace();
}
formatter_date.format(myDate,"dd.MM.yyyy"))
txtDate.setText(formatter_date.format(myDate,"dd.MM.yyyy")));

I want to have the date formatted as 28.Oct.2015 on a device set to English language, as 28.Okt.2015 in German, etc. So always one dot before and after the month abbreviation. When language is set to English it returns 28.Oct.2015 as it should, however, when Language is set to German it returns 28.Okt..2015 with two dots between Okt and 2015.

Is there any solution to handling this?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Franz
  • 358
  • 6
  • 18
  • 2
    As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use `java.time`, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Jan 19 '18 at 21:13
  • What result do you want? – Ole V.V. Jan 19 '18 at 21:16
  • A Standard Date in format dd.MMM.yyyy in for all possible Language Settings(Day.3Letters Month.Year) – Franz Jan 20 '18 at 16:52
  • Do I have any wrong settings or why are there two dots between month and year in the German Translation – Franz Jan 20 '18 at 16:53
  • Ah, I hadn’t noticed that. In German (as you no doubt know) the dot is used as sign of abbreviation, so the short form of *Oktober* is *Okt.* with a dot. In English, while a dot is sometimes used for a similar purpose, it is not used with the short form of month names, so *October* becomes *Oct* without a dot. No easy way around it that I can see. – Ole V.V. Jan 20 '18 at 18:24
  • I was hoping that the built-in localized formats would at least get you close, but no. The long German format is 28. Oktober 2015, while the medium format is 28.10.2015. None gives you the three letter month abbreviation. – Ole V.V. Jan 20 '18 at 18:49
  • 1
    In very many languages the months of June and July begin with the same three letters, including North Frisian (juuni, juuli) and French (juin, juillet). You may want to think again. See [Months of the year in many different languages](https://www.omniglot.com/language/time/months.htm). – Ole V.V. Jan 20 '18 at 18:56

3 Answers3

3

I should like to challenge what you are asking for. Of course you can have it, as your own answer already shows. But do you want it?

Use the built-in localized formats

Java has localized formats for all available locales (I think it’s all, in any case it’s many). I suggest you use these rather than your own idea of what a localized date should look like. While 28.Okt.2015 is probably commonplace in Austria and other German-speaking places, English-speaking people are not used to the dots in your format, and I would suspect that some people in the world will find it more or less strange.

I suggested in a comment that you add ThreeTenABP to your Android project in order to use java.time, the modern Java date and time API. It is so much nicer to work with. Now I am taking my own medicine:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
    LocalDate myDate = LocalDate.of(2015, Month.OCTOBER, 28);
    System.out.println(myDate.format(dateFormatter));

Output in different locales include:

German:     28.10.2015
UK English: 28 Oct 2015
French:     28 oct. 2015

It’s not what you asked for. And you may meet objections, but that will happen no matter which format you choose because many people have their own ideas about the proper formatting for their locale. It’s pretty standardized, though, so consider it.

Edit: where did the LocalDate come from?

I understood that you were converting from a string like "28.10.2015". Converting this to a LocalDate is straightforward when you know how:

    DateTimeFormatter numericDateFormatter = DateTimeFormatter.ofPattern("dd.MM.uuuu");
    LocalDate myDate = LocalDate.parse("28.10.2015", numericDateFormatter);

Only if you got a java.util.Date from a legacy API that you cannot change or do not want to change just now, first thing convert it to the modern Instant type and do further conversions from there:

    LocalDate myDate = oldfashionedJavaUtilDate.toInstant()
            .atZone(ZoneId.of("Europe/Vienna"))
            .toLocalDate();

Since this is a time zone sensitive operation, I recommend you specify an explicit time zone. You may use the JVM’s time zone setting by specifying ZoneId.systemDefault(), but be aware that this is fragile: the JVM setting may be changed under your feet by other parts of your program or other programs running in the same JVM.

What you asked for

The java.time edition of what you asked for is pretty similar to the code in your own answer:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd");
    DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM");
    DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("uuuu");
    LocalDate myDate = LocalDate.of(2015, Month.OCTOBER, 28);
    String dayOfMonth = myDate.format(dateFormatter);
    String monthName = myDate.format(monthFormatter);
    if (monthName.length() > 3) {
        monthName = monthName.substring(0, 3);
    }
    String year = myDate.format(yearFormatter);
    String formattedDate = dayOfMonth + '.' + monthName + '.' + year;
    System.out.println(formattedDate);

Output in the same locales as above:

German:     28.Okt.2015
UK English: 28.Oct.2015
French:     28.oct.2015

There is a much shorter way to obtain the same, though:

    String formattedDate = String.format("%1$td.%2$.3s.%1$tY", 
            myDate,
            myDate.getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault()));

It’s harder to read. It took me a number of attempts to get the format string %1$td.%2$.3s.%1$tY exactly right. And it will surprise those maintaining your code if they are used to DateTimeFormatter for formatting dates (and times). So I don’t really recommend it, but the choice is yours.

With another date I got the following output in French locale:

08.jui.2018

No French-speaking person, nor anyone else for that matter, will know whether this date was in June (juin) or July (juillet). In 57 of the available locales in my JVM, all 12 months of the year begin with the same three letters. Such locales include Tibetan, Swahili, Somali, Cornish, Scottish Gaelic and Vietnamese. In these languages nobody will be able to tell any months apart. Please think twice.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1
SimpleDateFormat dateFormat = new SimpleDateFormat(String pattern, Locale locale);

has another constructor with Locale change Locale.ENGLISH for date to be set in English. You can check other Locale options. I generally use Locale.getDefault() to display date in user's prefered language.

Thracian
  • 43,021
  • 16
  • 133
  • 222
0

Thanks for help but this solution works best for me

 DateFormat formatter_month = new SimpleDateFormat("MMMM"); //Get Whole Name of Month
 DateFormat formatter_day = new SimpleDateFormat("dd."); //Get Day + Dot(2 digits)
 DateFormat formatter_year = new SimpleDateFormat(".yyyy"); //Get Dot + Year(4 digits)
 String str_date = formatter_day.format(date)+  //Day
 formatter_month.format(date).substring(0,3)+   //Month
 formatter_year.format(date);   //Year
Franz
  • 358
  • 6
  • 18
  • 1
    Good that you found a solution. Please take into account that the month name may already be shorter than three letters. In Creole, May is *me*. You are not likely to find a device with Sercquiais language, but if you do, August is *u*, just one letter. – Ole V.V. Jan 20 '18 at 19:22
  • 2
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 21 '18 at 00:38