J'ai une application multiculturelle, le projet utilise Java 7. J'ai besoin d'afficher la date, mais le jour en mois et en mois uniquement. Ainsi par exemple dans Locale.UK la date d'aujourd'hui ressemble à: 24/01, mais dans Locale.US comme: 1/24. Comment y parvenir en Java 7? J'ai essayé d'utiliser DateFormat.getDateInstance(dateFormat, locale), mais dans ce cas, je peux utiliser uniquement des formats de date prédéfinis, par exemple DateFormat.SHORT, DateFormat.DEFAULT etc. il n'y a pas de format prédéfini juste avec le jour en mois et en mois seulement. Ensuite, j'ai essayé d'utiliser SimpleDateFormat avec les paramètres régionaux, mais cela ne fonctionne pas comme je me le demande, cela traduit simplement du texte en fonction des paramètres régionaux. Voici mon exemple de code:

DateFormat dfuk = DateFormat.getDateInstance(DateFormat.SHORT, Locale.UK);
DateFormat dfus = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
System.out.println(dfuk.format(new Date()));  // 24/01/17
System.out.println(dfus.format(new Date()));  // 1/24/17
SimpleDateFormat sdfuk = new SimpleDateFormat("dd/MM", Locale.UK);
SimpleDateFormat sdfus = new SimpleDateFormat("dd/MM", Locale.US);
System.out.println(sdfuk.format(new Date()));  // 24/01
System.out.println(sdfus.format(new Date()));  // 24/01

Je m'attendais à ce que la dernière ligne imprime 01/24 (ou 1/24). Comment y parvenir?

3
bladekp 24 janv. 2017 à 23:01

3 réponses

Meilleure réponse

Remplacez votre troisième dernière ligne par

SimpleDateFormat sdfus = new SimpleDateFormat("MM/dd", Locale.US);

Surmonter les lacunes de l'offre Java standard:

La méthode getDateInstance() prend un argument pour style. Le style le plus court semble être DateFormat.SHORT. Vous pouvez argumenter qu'ils devraient peut-être en fournir un qui soit encore plus court (DateFormat.SHORTER peut-être?) C.f.

http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html#getDateInstance(int)

Avant que cela ne se produise, vous pouvez créer une énumération de motifs pour le style le plus court. Voici un exemple:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

enum PatternShorter { // or PatternMonthDayOnly
    MM_SLASH_DD     ("MM/dd")
    , DD_SLASH_MM   ("dd/MM")
    ;
    private String pattern;

    public String getPattern() {
        return pattern;
    }

    private PatternShorter(String pattern) {
        this.pattern = pattern;
    }

    public static PatternShorter getDefault() { return DD_SLASH_MM; }
}

public class DateFormatEx {
    private static Map<Locale, PatternShorter> patternShorter = new HashMap<>();

    static {
        patternShorter.put(Locale.UK, PatternShorter.DD_SLASH_MM);
        patternShorter.put(Locale.UK, PatternShorter.MM_SLASH_DD);
        // any locale not listed here will get the default pattern
    }

    private static String getPattern (Locale locale) {      
        if (patternShorter.get(locale)!=null) {
            return patternShorter.get(locale).getPattern();
        } else {
            return PatternShorter.getDefault().getPattern();
        }
    }

    public static void main(String[] args) {
        List<Locale> listOfLocale = Arrays.asList(Locale.UK, Locale.US, Locale.FRENCH);
        for (Locale locale : listOfLocale) {
            SimpleDateFormat fmt 
            = new SimpleDateFormat(getPattern(locale), locale);
            System.out.format("for locale %s the shorter date/month display is: %s%n"
                    , locale.toString()
                    , fmt.format(new Date()));  
        }
    }

}

La sortie serait:

for locale en_GB the shorter date/month display is: 01/24
for locale en_US the shorter date/month display is: 24/01
for locale fr the shorter date/month display is: 24/01
1
leeyuiwah 24 janv. 2017 à 20:35

Votre code a lancé le même format, car les deux DateFormat ont été construits avec le même modèle et ce n'est pas correct.

SimpleDateFormat sdfuk = new SimpleDateFormat("dd/MM", Locale.UK);
SimpleDateFormat sdfus = new SimpleDateFormat("dd/MM", Locale.US);

Vous aurez besoin du local si vous avez une chaîne qui va être convertie en date ... pour l'analyse que vous essayez de faire (chaîne -> Date) seul le modèle est correct ...

Exemple

DateFormat sdfuk = new SimpleDateFormat("dd/MM");
DateFormat sdfus = new SimpleDateFormat("MM/d");
System.out.println(sdfuk.format(new Date())); // 24/01
System.out.println(sdfus.format(new Date())); // 01/24
2
ΦXocę 웃 Пepeúpa ツ 24 janv. 2017 à 20:13

J'ai fini par modifier la chaîne de format localisé fournie par DateFormat.getDateInstance(DateFormat.SHORT), en supprimant la partie année du format:

DateFormat shortDateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
String shortPattern = ((SimpleDateFormat) shortDateFormat).toLocalizedPattern();
String shorterPattern = shortPattern.replaceAll("[/\\- ]*[yY]+[^a-zA-Z]*", "");
DateFormat shorterDateFormat = new SimpleDateFormat(shorterPattern);

J'ai parcouru les 734 locales fournies par mon système, et les modèles de date générés semblent bons pour tous, pour autant que je sache.

Quelques exemples comparant le modèle court d'origine au modèle plus court modifié:

         short      shorter
en_US    M/d/yy     M/d
en_GB    dd/MM/y    dd/MM
de_DE    dd.MM.yy   dd.MM.
fr_FR    dd/MM/y    dd/MM
nl_NL    dd-MM-y    dd-MM
ja_JP    y/MM/dd    MM/dd
0
Floern 9 mars 2020 à 22:43