SimpleDateFormat et chaîne de format basée sur les parameters régionaux

J’essaie de formater une date en Java de différentes manières en fonction de l’environnement local donné. Par exemple, je souhaite que les utilisateurs anglais voient “Nov 1, 2009” (formaté par “MMM d, aaaa”) et les utilisateurs norvégiens pour voir “1. nov. 2009” (“d. MMM. Yyyy”).

La partie mois fonctionne correctement si j’ajoute les parameters régionaux au constructeur SimpleDateFormat, mais qu’en est-il du rest?

J’espérais pouvoir append des chaînes de format associées à des parameters régionaux à SimpleDateFormat, mais je ne trouve aucun moyen de le faire. Est-ce possible ou dois-je laisser mon code vérifier les parameters régionaux et append la chaîne de format correspondante?

Utilisez DateFormat.getDateInstance (style int, parameters régionaux) au lieu de créer vos propres modèles avec SimpleDateFormat .

 SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH); Ssortingng formatted = dateFormat.format(the_date_you_want_here); 

Utilisez le style + locale : DateFormat.getDateInstance (int style, locale locale)

Vérifiez http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html

Exécutez l’exemple suivant pour voir les différences:

 import java.text.DateFormat; import java.util.Date; import java.util.Locale; public class DateFormatDemoSO { public static void main(Ssortingng args[]) { int style = DateFormat.MEDIUM; //Also try with style = DateFormat.FULL and DateFormat.SHORT Date date = new Date(); DateFormat df; df = DateFormat.getDateInstance(style, Locale.UK); System.out.println("United Kingdom: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.US); System.out.println("USA: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.FRANCE); System.out.println("France: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.ITALY); System.out.println("Italy: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.JAPAN); System.out.println("Japan: " + df.format(date)); } } 

Sortie:

 United Kingdom: 25-Sep-2017 USA: Sep 25, 2017 France: 25 sept. 2017 Italy: 25-set-2017 Japan: 2017/09/25 

tl; dr

 LocalDate.now().format( DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ) .withLocale( new Locale( "no" , "NO" ) ) ) 

Les classes gênantes de java.util.Date et de SimpleDateFormat sont désormais héritées, supplantées par les classes java.time.

LocalDate

La classe LocalDate représente une valeur de date uniquement sans heure et sans fuseau horaire.

Un fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie dans le monde entier par zone. Par exemple, quelques minutes après minuit à Paris, la France est une nouvelle journée alors qu’elle est encore «hier» à Montréal, au Québec .

 ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z ); 

DateTimeFormatter

Utilisez DateTimeFormatter pour générer des chaînes représentant uniquement la partie date ou la partie heure.

La classe DateTimeFormatter peut automatiquement être localisée .

Pour localiser, spécifiez:

  • FormatStyle pour déterminer la longueur ou l’abréviation de la chaîne.
  • Locale pour déterminer (a) le langage humain pour la traduction du nom du jour, du nom du mois et autres, et (b) des normes culturelles déterminant les questions d’abréviation, de majuscule, de ponctuation et autres.

Exemple:

 Locale l = Locale.CANADA_FRENCH ; DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l ); Ssortingng output = ld.format( f ); 

Dans l’autre direction, vous pouvez parsingr une chaîne localisée.

 LocalDate ld = LocalDate.parse( input , f ); 

Notez que les parameters régionaux et le fuseau horaire sont des problèmes complètement orthogonaux. Vous pouvez avoir un moment montréalais présenté en japonais ou un moment à Auckland en Nouvelle-Zélande présenté en langue hindi.

Autre exemple: Change 6 junio 2012 (espagnol) au 2012-06-06 (format standard ISO 8601 ). Les classes java.time utilisent les formats ISO 8601 par défaut pour parsingr / générer des chaînes.

 Ssortingng input = "6 junio 2012"; Locale l = new Locale ( "es" , "ES" ); DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l ); LocalDate ld = LocalDate.parse ( input , f ); Ssortingng output = ld.toSsortingng(); // 2012-06-06. 

Formats de lecture

Voici un exemple de code permettant de lire automatiquement les résultats de plusieurs formats dans plusieurs environnements locaux.

Un EnumSet est une implémentation de Set , hautement optimisée pour une faible utilisation de mémoire et une vitesse d’exécution rapide lors de la collecte d’objects Enum . Ainsi, EnumSet.allOf( FormatStyle.class ) nous donne une collection des quatre objects énumération FormatStyle à boucler. Pour plus d’informations, voir Tutoriel Oracle sur les types enum .

 LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ); List < Locale > locales = new ArrayList <>( 3 ); locales.add( Locale.CANADA_FRENCH ); locales.add( new Locale( "no" , "NO" ) ); locales.add( Locale.US ); // Or use all locales (almost 800 of them, for about 120K text results). // Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them. for ( Locale locale : locales ) { System.out.println( "------| LOCALE: " + locale + " — " + locale.getDisplayName() + " |----------------------------------" + System.lineSeparator() ); for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) ) { DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale ); String output = ld.format( f ); System.out.println( output ); } System.out.println( "" ); } System.out.println( "« fin »" + System.lineSeparator() ); 

Sortie.

 ------| LOCALE: fr_CA — French (Canada) |---------------------------------- mardi 23 janvier 2018 23 janvier 2018 23 janv. 2018 18-01-23 ------| LOCALE: no_NO — Norwegian (Norway) |---------------------------------- tirsdag 23. januar 2018 23. januar 2018 23. jan. 2018 23.01.2018 ------| LOCALE: en_US — English (United States) |---------------------------------- Tuesday, January 23, 2018 January 23, 2018 Jan 23, 2018 1/23/18 « fin » 

À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes de date / heure héritées telles que java.util.Date , Calendar et SimpleDateFormat .

Le projet Joda-Time , maintenant en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Vous pouvez échanger des objects java.time directement avec votre firebase database. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de classes java.sql.* .

Où obtenir les classes java.time?

  • Java SE 8 , Java SE 9 et versions ultérieures
    • Intégré
    • Partie de l’API Java standard avec une implémentation intégrée.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie de la fonctionnalité java.time est transférée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android
    • Versions ultérieures des implémentations de bundles Android des classes java.time.
    • Pour Android antérieur, le projet ThreeTenABP adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts futurs à java.time. Vous pouvez y trouver des classes utiles telles que Interval , YearWeek , YearQuarter , etc.

Localisation de la chaîne de date:

Basé sur le post de redsonic:

 private Ssortingng localizeDate(Ssortingng inputdate, Locale locale) { Date date = new Date(); SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); try { date = dateFormat.parse(inputdate); } catch (ParseException e) { log.warn("Input date was not correct. Can not localize it."); return inputdate; } return dateFormatCN.format(date); } Ssortingng localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN")); 

sera comme 05- 九月 -2013

Cela affichera la date en fonction des parameters régionaux de l’utilisateur:

 import java.text.DateFormat; import java.util.Date; Date date = new Date(); DateFormat df = DateFormat.getDateTimeInstance(); Ssortingng myDate = df.format(date); 

31 déc. 1969 19:00:02

 DateFormat.getDateInstance() 

31 décembre 1969

 Ssortingng text = new SimpleDateFormat("E, MMM d, yyyy").format(date); 

Java 8 Style pour une date donnée

 LocalDate today = LocalDate.of(1982, Month.AUGUST, 31); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE))); 

Java8

  import java.time.format.DateTimeFormatter; myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))