web-dev-qa-db-fra.com

Comment convertir un entier en un nom de mois localisé en Java?

Je reçois un entier et j'ai besoin de convertir en noms de mois dans différents endroits:

Exemple pour locale en-us:
1 -> janvier
2 -> février

Exemple pour la locale es-mx:
1 -> Enero
2 -> Febrero

93
atomsfat
import Java.text.DateFormatSymbols;
public String getMonth(int month) {
    return new DateFormatSymbols().getMonths()[month-1];
}
199
joe

Vous devez utiliser LLLL pour les noms de mois autonomes. ceci est documenté dans la documentation SimpleDateFormat, telle que:

SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
32
Ilya Lisway

Je voudrais utiliser SimpleDateFormat. Quelqu'un me corrige s’il existe un moyen plus facile de créer un calendrier mensuel, je le fais maintenant avec du code et je n’en suis pas si sûr.

import Java.text.DateFormat;
import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.GregorianCalendar;


public String formatMonth(int month, Locale locale) {
    DateFormat formatter = new SimpleDateFormat("MMMM", locale);
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    calendar.set(Calendar.MONTH, month-1);
    return formatter.format(calendar.getTime());
}
16
stevedbrown

tl; dr

Month                             // Enum class, predefining and naming a dozen objects, one for each month of the year. 
.of( 12 )                         // Retrieving one of the enum objects by number, 1-12. 
.getDisplayName(
    TextStyle.FULL_STANDALONE , 
    Locale.CANADA_FRENCH          // Locale determines the human language and cultural norms used in localizing. 
)

Java.time

Depuis Java 1.8 (ou 1.7 & 1.6 avec le ThreeTen-Backport ), vous pouvez utilisez ceci:

Month.of(integerMonth).getDisplayName(TextStyle.FULL_STANDALONE, locale);

Notez que integerMonth est basé sur 1, c’est-à-dire que 1 correspond à janvier. La plage est toujours comprise entre 1 et 12 janvier/décembre (calendrier grégorien uniquement).

15
Oliv

Voici comment je le ferais. Je vais quitter la plage en vérifiant le int month dépend de vous.

import Java.text.DateFormatSymbols;

public String formatMonth(int month, Locale locale) {
    DateFormatSymbols symbols = new DateFormatSymbols(locale);
    String[] monthNames = symbols.getMonths();
    return monthNames[month - 1];
}
14
Bill the Lizard

Utilisation de SimpleDateFormat.

import Java.text.SimpleDateFormat;

public String formatMonth(String month) {
    SimpleDateFormat monthParse = new SimpleDateFormat("MM");
    SimpleDateFormat monthDisplay = new SimpleDateFormat("MMMM");
    return monthDisplay.format(monthParse.parse(month));
}


formatMonth("2"); 

Résultat: février

10
Terence

Apparemment, dans Android 2.2, il y a un bogue avec SimpleDateFormat.

Pour utiliser les noms de mois, vous devez les définir vous-même dans vos ressources:

<string-array name="month_names">
    <item>January</item>
    <item>February</item>
    <item>March</item>
    <item>April</item>
    <item>May</item>
    <item>June</item>
    <item>July</item>
    <item>August</item>
    <item>September</item>
    <item>October</item>
    <item>November</item>
    <item>December</item>
</string-array>

Et ensuite, utilisez-les dans votre code comme ceci:

/**
 * Get the month name of a Date. e.g. January for the Date 2011-01-01
 * 
 * @param date
 * @return e.g. "January"
 */
public static String getMonthName(Context context, Date date) {

    /*
     * Android 2.2 has a bug in SimpleDateFormat. Can't use "MMMM" for
     * getting the Month name for the given Locale. Thus relying on own
     * values from string resources
     */

    String result = "";

    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    int month = cal.get(Calendar.MONTH);

    try {
        result = context.getResources().getStringArray(R.array.month_names)[month];
    } catch (ArrayIndexOutOfBoundsException e) {
        result = Integer.toString(month);
    }

    return result;
}
7
IHeartAndroid

tl; dr

Month.of( yourMonthNumber )           // Represent a month by its number, 1-12 for January-December. 
  .getDisplayName(                    // Generate text of the name of the month automatically localized. 
      TextStyle.SHORT_STANDALONE ,    // Specify how long or abbreviated the name of month should be.
      new Locale( "es" , "MX" )       // Locale determines (a) the human language used in translation, and (b) the cultural norms used in deciding issues of abbreviation, capitalization, punctuation, and so on.
  )                                   // Returns a String.

Java.time.Month

Il est beaucoup plus facile de faire maintenant dans les classes Java.time qui supplantent ces anciennes classes fastidieuses héritées.

L'énumération Month définit une douzaine d'objets, un pour chaque mois.

Les mois sont numérotés de 1 à 12 pour les mois de janvier à décembre.

Month month = Month.of( 2 );  // 2 → February.

Demandez à l'objet de générer une chaîne de la chaîne nom du mois, automatiquement localisé .

Ajustez le TextStyle pour spécifier la durée ou l’abréviation du nom. Notez que dans certaines langues (pas l'anglais), le nom du mois varie s'il est utilisé seul ou dans le cadre d'une date complète. Donc, chaque style de texte a un …_STANDALONE une variante.

Spécifiez un Locale pour déterminer:

  • Quelle langue humaine devrait être utilisée dans la traduction.
  • Quelles normes culturelles devraient trancher des questions telles que l’abréviation, la ponctuation et la capitalisation.

Exemple:

Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l );  // Or Locale.US, Locale.CANADA_FRENCH. 

Nom → Month objet

Pour votre information, aller dans l'autre sens (analyser une chaîne avec le nom du mois pour obtenir un objet Month enum) n'est pas intégré. Vous pouvez écrire votre propre classe pour le faire. Voici ma tentative rapide d'une telle classe. Utilisez-le à vos risques et périls . J'ai donné à ce code aucune pensée sérieuse ni aucun test sérieux.

Usage.

Month m = MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) ;  // Month.JANUARY

Code.

package com.basilbourque.example;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import Java.time.Month;
import Java.time.format.TextStyle;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.Locale;

// For a given name of month in some language, determine the matching `Java.time.Month` enum object.
// This class is the opposite of `Month.getDisplayName` which generates a localized string for a given `Month` object.
// Usage… MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) → Month.JANUARY
// Assumes `FormatStyle.FULL`, for names without abbreviation.
// About `Java.time.Month` enum: https://docs.Oracle.com/javase/9/docs/api/Java/time/Month.html
// USE AT YOUR OWN RISK. Provided without guarantee or warranty. No serious testing or code review was performed.
public class MonthDelocalizer
{
    @NotNull
    private Locale locale;

    @NotNull
    private List < String > monthNames, monthNamesStandalone; // Some languages use an alternate spelling for a “standalone” month name used without the context of a date.

    // Constructor. Private, for static factory method.
    private MonthDelocalizer ( @NotNull Locale locale )
    {
        this.locale = locale;

        // Populate the pair of arrays, each having the translated month names.
        int countMonthsInYear = 12; // Twelve months in the year.
        this.monthNames = new ArrayList <>( countMonthsInYear );
        this.monthNamesStandalone = new ArrayList <>( countMonthsInYear );

        for ( int i = 1 ; i <= countMonthsInYear ; i++ )
        {
            this.monthNames.add( Month.of( i ).getDisplayName( TextStyle.FULL , this.locale ) );
            this.monthNamesStandalone.add( Month.of( i ).getDisplayName( TextStyle.FULL_STANDALONE , this.locale ) );
        }
//        System.out.println( this.monthNames );
//        System.out.println( this.monthNamesStandalone );
    }

    // Constructor. Private, for static factory method.
    // Personally, I think it unwise to default implicitly to a `Locale`. But I included this in case you disagree with me, and to follow the lead of the *Java.time* classes. --Basil Bourque
    private MonthDelocalizer ( )
    {
        this( Locale.getDefault() );
    }

    // static factory method, instead of  constructors.
    // See article by Dr. Joshua Bloch. http://www.informit.com/articles/article.aspx?p=1216151
    // The `Locale` argument determines the human language and cultural norms used in de-localizing input strings.
    synchronized static public MonthDelocalizer of ( @NotNull Locale localeArg )
    {
        MonthDelocalizer x = new MonthDelocalizer( localeArg ); // This class could be optimized by caching this object.
        return x;
    }

    // Attempt to translate the name of a month to look-up a matching `Month` enum object.
    // Returns NULL if the passed String value is not found to be a valid name of month for the human language and cultural norms of the `Locale` specified when constructing this parent object, `MonthDelocalizer`.
    @Nullable
    public Month parse ( @NotNull String input )
    {
        int index = this.monthNames.indexOf( input );
        if ( - 1 == index )
        { // If no hit in the contextual names, try the standalone names.
            index = this.monthNamesStandalone.indexOf( input );
        }
        int ordinal = ( index + 1 );
        Month m = ( ordinal > 0 ) ? Month.of( ordinal ) : null;  // If we have a hit, determine the `Month` enum object. Else return null.
        if ( null == m )
        {
            throw new Java.lang.IllegalArgumentException( "The passed month name: ‘" + input + "’ is not valid for locale: " + this.locale.toString() );
        }
        return m;
    }

    // `Object` class overrides.

    @Override
    public boolean equals ( Object o )
    {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;

        MonthDelocalizer that = ( MonthDelocalizer ) o;

        return locale.equals( that.locale );
    }

    @Override
    public int hashCode ( )
    {
        return locale.hashCode();
    }

    public static void main ( String[] args )
    {
        // Usage example:
        MonthDelocalizer monthDelocJapan = MonthDelocalizer.of( Locale.JAPAN );
        try
        {
            Month m = monthDelocJapan.parse( "pink elephant" ); // Invalid input.
        } catch ( IllegalArgumentException e )
        {
            // … handle error
            System.out.println( "ERROR: " + e.getLocalizedMessage() );
        }

        // Ignore exception. (not recommended)
        if ( MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ).equals( Month.JANUARY ) )
        {
            System.out.println( "GOOD - In locale "+Locale.CANADA_FRENCH+", the input ‘janvier’ parses to Month.JANUARY." );
        }
    }
}

À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien problème - legacy classes date-heure telles que Java.util.Date , Calendar , & SimpleDateFormat .

Le projet Joda-Time , maintenant en mode de maintenance , conseille de migrer vers le Java.time = cours.

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

Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou une version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.* Des classes.

Où obtenir les classes Java.time?

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval , YearWeek , YearQuarter , et plus .

6
Basil Bourque

Il existe un problème lorsque vous utilisez la classe DateFormatSymbols pour que sa méthode getMonthName obtienne Mois par Nom, il affiche Mois par Numéro dans certains Android périphériques. J'ai résolu ce problème en procédant de la manière suivante:

Dans String_array.xml

<string-array name="year_month_name">
    <item>January</item>
    <item>February</item>
    <item>March</item>
    <item>April</item>
    <item>May</item>
    <item>June</item>
    <item>July</item>
    <item>August</item>
    <item>September</item>
    <item>October</item>
    <item>November</item>
    <item>December</item>
    </string-array>

Dans Java la classe appelle simplement ce tableau comme suit:

public String[] getYearMonthName() {
        return getResources().getStringArray(R.array.year_month_names);
        //or like 
       //return cntx.getResources().getStringArray(R.array.month_names);
    } 

      String[] months = getYearMonthName(); 
           if (i < months.length) {
            monthShow.setMonthName(months[i] + " " + year);

            }

Bonne codage :)

1
Faakhir
    public static void main(String[] args) {
    SimpleDateFormat format = new SimpleDateFormat("MMMMM", new Locale("en", "US"));
    System.out.println(format.format(new Date()));
}
0
Diogo Oliveira

extension de Kotlin

fun Int.toMonthName(): String {
    return DateFormatSymbols().months[this]
}

tilisation

calendar.get(Calendar.MONTH).toMonthName()
0
Sadda Hussain

Essayez de l'utiliser de manière très simple et appelez-le comme votre propre fonction

public static String convertnumtocharmonths(int m){
         String charname=null;
         if(m==1){
             charname="Jan";
         }
         if(m==2){
             charname="Fev";
         }
         if(m==3){
             charname="Mar";
         }
         if(m==4){
             charname="Avr";
         }
         if(m==5){
             charname="Mai";
         }
         if(m==6){
             charname="Jun";
         }
         if(m==7){
             charname="Jul";
         }
         if(m==8){
             charname="Aou";
         }
         if(m==9){
             charname="Sep";
         }
         if(m==10){
             charname="Oct";
         }
         if(m==11){
             charname="Nov";
         }
         if(m==12){
             charname="Dec";
         }
         return charname;
     }
0
Samer

Il suffit d'insérer la ligne

DateFormatSymbols.getInstance().getMonths()[view.getMonth()] 

fera l'affaire.

0
Kingsley Ijike