web-dev-qa-db-fra.com

Comment obtenir une chaîne de modèle de date localisée?

Il est assez facile de formater et d’analyser les classes Java Date (ou Calendar) en utilisant l’instance de DateFormat , c’est-à-dire que je pourrais formater la date actuelle en une courte date de localisation comme ceci:

DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String today = formatter.format(new Date());

Mon problème est le suivant: je dois obtenir cette chaîne de modèle localisée (c'est-à-dire quelque chose comme "MM/dd/yy"). Cela devrait être une tâche triviale, mais je ne pouvais tout simplement pas trouver le fournisseur ...

41
Paweł Dyda

Pour ceux qui utilisent encore Java 7 et les versions antérieures:

Vous pouvez utiliser quelque chose comme ceci:

DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String pattern       = ((SimpleDateFormat)formatter).toPattern();
String localPattern  = ((SimpleDateFormat)formatter).toLocalizedPattern();

Étant donné que DateFormat renvoyé De getDateInstance() est une instance de SimpleDateFormat. Ces deux méthodes devraient également figurer dans DateFormat afin que cela soit moins efficace, mais elles ne le sont pas actuellement.

29
Zarremgregarrok

C'est peut-être étrange que je réponde à ma propre question, mais je pense pouvoir ajouter quelque chose à l'image.

Mise en œuvre de l'USI

Évidemment, Java 8 vous en donne beaucoup, mais il y a aussi autre chose: ICU4J . C’est en fait la source de l’implémentation originale en Java d'éléments tels que Calendar, DateFormat et SimpleDateFormat, pour en nommer quelques-uns.
Par conséquent, il ne devrait pas être surprenant que SimpleDateFormat de ICU contienne également des méthodes telles que toPattern() ou toLocalizedPattern(). Vous pouvez les voir en action ici:

DateFormat fmt = DateFormat.getPatternInstance(
        DateFormat.YEAR_MONTH,
        Locale.forLanguageTag("pl-PL"));

if (fmt instanceof SimpleDateFormat) {
    SimpleDateFormat sfmt = (SimpleDateFormat) fmt;
    String pattern = sfmt.toPattern();
    String localizedPattern = sfmt.toLocalizedPattern();
    System.out.println(pattern);
    System.out.println(localizedPattern);
}

Améliorations ICU

Ce n'est pas nouveau, mais ce que je voulais vraiment souligner, c'est ceci:

DateFormat.getPatternInstance(String pattern, Locale locale);

Ceci est une méthode qui peut renvoyer une multitude de modèles spécifiques aux paramètres régionaux, tels que:

  • ABBR_QUARTER
  • TRIMESTRE
  • ANNÉE
  • YEAR_ABBR_QUARTER
  • YEAR_QUARTER
  • YEAR_ABBR_MONTH
  • ANNÉE MOIS
  • YEAR_NUM_MONTH
  • YEAR_ABBR_MONTH_DAY
  • YEAR_NUM_MONTH_DAY
  • ANNÉE MOIS JOUR
  • YEAR_ABBR_MONTH_WEEKDAY_DAY
  • YEAR_MONTH_WEEKDAY_DAY
  • YEAR_NUM_MONTH_WEEKDAY_DAY
  • ABBR_MONTH
  • MOIS
  • NUM_MONTH
  • ABBR_STANDALONE_MONTH
  • STANDALONE_MONTH
  • ABBR_MONTH_DAY
  • MOIS_DAY
  • NUM_MONTH_DAY
  • ABBR_MONTH_WEEKDAY_DAY
  • MONTH_WEEKDAY_DAY
  • NUM_MONTH_WEEKDAY_DAY
  • JOURNÉE
  • ABBR_WEEKDAY
  • JOUR DE LA SEMAINE
  • HEURE
  • HEURE24
  • HOUR_MINUTE
  • HOUR_MINUTE_SECOND
  • HOUR24_MINUTE
  • HOUR24_MINUTE_SECOND
  • HOUR_TZ
  • HOUR_GENERIC_TZ
  • HOUR_MINUTE_TZ
  • HOUR_MINUTE_GENERIC_TZ
  • MINUTE
  • MINUTE_SECOND
  • SECONDE
  • ABBR_UTC_TZ
  • ABBR_SPECIFIC_TZ
  • SPECIFIC_TZ
  • ABBR_GENERIC_TZ
  • GENERIC_TZ
  • LOCATION_TZ

Bien sûr, il y en a plusieurs. Ce qui est bien avec eux, c’est que ces modèles sont en réalité des chaînes (comme dans Java.lang.String), c’est-à-dire que si vous utilisez le modèle anglais "MM/d", vous obtiendrez un modèle spécifique à la localisation. Cela pourrait être utile dans certains cas. Habituellement, vous utiliseriez simplement une instance DateFormat, sans vous soucier du modèle lui-même.

Motif spécifique à la région vs motif localisé

L'intention de la question était d'obtenir la localisation, et non le modèle spécifique à l'environnement local. Quelle est la différence?

En théorie, toPattern() vous donnera un modèle spécifique aux paramètres régionaux (en fonction de Locale que vous avez utilisé pour instancier (Simple)DateFormat). Quelle que soit la langue/le pays cible que vous choisissez, vous obtiendrez un modèle composé de symboles tels que y, M, d, h, H, M, etc.

D'autre part, toLocalizedPattern()devrait renvoyer un modèle localisé, qui convient aux utilisateurs finaux pour la lecture et la compréhension. Par exemple, le modèle de date moyen allemand (par défaut) serait:

  • toPattern (): jj.MM.yyyy
  • toLocalizedPattern (): tt.MM.jjjj (jour = balise, mois = mois, année = année)

L'intention de la question était la suivante: "Comment trouver le modèle localisé qui pourrait servir d'indice quant au format de date/heure". Autrement dit, disons que nous avons un champ de date que l'utilisateur peut renseigner à l'aide du modèle spécifique à l'environnement local, mais je souhaite afficher un indicateur de format dans le formulaire localisé.

Malheureusement, jusqu'à présent, il n'y a pas de bonne solution. Le ICU que j'ai mentionné plus tôt dans cet article fonctionne partiellement. En effet, les données utilisées par ICU proviennent de CLDR , qui est malheureusement partiellement traduit/partiellement correct. Dans le cas de la langue de ma mère, au moment de la rédaction, ni les motifs, ni leurs formes localisées ne sont correctement traduits. Et chaque fois que je les corrige, je me suis fait élire par d'autres personnes qui ne vivaient pas nécessairement en Pologne et ne parlaient pas le polonais ... 

La morale de cette histoire: ne vous fiez pas entièrement au CLDR. Vous devez toujours avoir des auditeurs/réviseurs linguistiques locaux.

19
Paweł Dyda

Vous pouvez utiliser DateTimeFormatterBuilder en Java 8. L’exemple suivant renvoie un modèle de date localisée, par exemple "d.M.yyyy".

String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
  FormatStyle.SHORT, null, IsoChronology.INSTANCE, 
  Locale.GERMANY); // or whatever Locale
11
mikaves

Le code suivant vous donnera le modèle pour les paramètres régionaux:

final String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale)).toPattern();
System.out.println(pattern1);
5
Andreas Kozma

Java 8 fournit certaines fonctionnalités prêtes à l'emploi pour travailler avec le formatage/l'analyse de la date et de l'heure, y compris la gestion des paramètres régionaux. Voici une brève introduction.

Patterns de base

Dans le cas le plus simple pour formater/analyser une date, vous utiliseriez le code suivant avec un modèle de chaîne:

DateTimeFormatter.ofPattern("MM/dd/yyyy")

La norme consiste alors à utiliser cela avec l'objet date directement pour le formatage:

return LocalDate.now().format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));

Et ensuite, en utilisant le modèle d'usine pour analyser une date:

return LocalDate.parse(dateString, DateTimeFormatter.ofPattern("MM/dd/yyyy"));

Le modèle lui-même comporte un grand nombre d'options couvrant la majorité des cas. Un récapitulatif complet est disponible à l'emplacement javadoc ici .

Locales

L'inclusion d'un paramètre régional est relativement simple. Pour le paramètre régional par défaut, vous disposez des options suivantes qui peuvent ensuite être appliquées aux options de format/analyse présentées ci-dessus:

DateTimeFormatter.ofLocalizedDate(dateStyle);

Le 'dateStyle' ci-dessus est une option FormatStyle Enum qui représente les versions complètes, longues, moyennes et courtes de la Date localisée lorsque vous utilisez la DateTimeFormatter. En utilisant FormatStyle , vous disposez également des options suivantes:

DateTimeFormatter.ofLocalizedTime(timeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle, timeStyle);

La dernière option vous permet de spécifier un FormatStyle différent pour la date et l'heure. Si vous ne travaillez pas avec les paramètres régionaux par défaut, le retour de chacune des méthodes localisées peut être ajusté à l'aide de l'option .withLocale, par exemple.

DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(Locale.ENGLISH);

Sinon, ofPattern a une version surchargée pour spécifier également les paramètres régionaux.

DateTimeFormatter.ofPattern("MM/dd/yyyy",Locale.ENGLISH);

J'ai besoin de plus!

DateTimeFormatter répondra à la majorité des cas d'utilisation, mais il est construit sur le DateTimeFormatterBuilder , qui fournit une vaste gamme d'options à l'utilisateur du générateur. Utilisez DateTimeFormatter pour commencer et si vous avez besoin de ces fonctionnalités de mise en forme étendues, faites appel au constructeur.

4
Jim

Veuillez trouver ci-dessous le code qui accepte l’instance de locale et renvoie le format/modèle de données spécifique à la locale.

 public static String getLocaleDatePattern(Locale locale) {
    // Validating if Locale instance is null
    if (locale == null || locale.getLanguage() == null) {
        return "MM/dd/yyyy";
    }
    // Fetching the locale specific date pattern
    String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance(
            DateFormat.SHORT, locale)).toPattern();
    // Validating if locale type is having language code for Chinese and country 
    // code for (Hong Kong) with Date Format as - yy'?'M'?'d'?'
    if (locale.toString().equalsIgnoreCase("zh_hk")) {
        // Expected application Date Format for Chinese (Hong Kong) locale type
        return "yyyy'MM'dd";
    }
    // Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern
    localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd").replaceAll(
            "M{1,2}", "MM").replaceAll("y{1,4}|Gy", "yyyy");
    // Replacing all blank spaces in the locale date pattern
    localeDatePattern = localeDatePattern.replace(" ", "");
    // Validating the date pattern length to remove any extract characters
    if (localeDatePattern.length() > 10) {
        // Keeping the standard length as expected by the application
        localeDatePattern = localeDatePattern.substring(0, 10);
    }
    return localeDatePattern;
}
1
Dinesh Lomte

Comme il ne s’agit que des paramètres régionaux informations , je pense que vous devrez alors localiser le fichier que la JVM (OpenJDK ou Harmony) utilise réellement comme entrée de l’ensemble Locale et comprendre comment analyser le. Ou utilisez simplement une autre source sur le Web (il y a sûrement une liste quelque part). Cela sauvera ces pauvres traducteurs.

0
David Bullock