Hoe kan ik een geheel getal converteren naar een gelokaliseerde maandnaam in Java?

Ik krijg een geheel getal en ik moet namen in verschillende talen converteren naar een maand:

Voorbeeld voor locale en-us:
1 -> januari
2 -> februari

Voorbeeld voor landinstelling es-mx:
1 -> Enero
2 -> Febrero


Antwoord 1, autoriteit 100%

import java.text.DateFormatSymbols;
public String getMonth(int month) {
    return new DateFormatSymbols().getMonths()[month-1];
}

Antwoord 2, autoriteit 15%

U moet LLLL gebruiken voor zelfstandige maandnamen. dit is gedocumenteerd in de SimpleDateFormatdocumentatie, zoals:

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

Antwoord 3, autoriteit 15%

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

Sinds Java 1.8 (of 1.7 & 1.6 met de ThreeTen-Backport) je kunt dit gebruiken:

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

Houd er rekening mee dat integerMonth1-gebaseerd is, d.w.z. 1 is voor januari. Bereik is altijd van 1 tot 12 voor januari-december (d.w.z. alleen Gregoriaanse kalender).


Antwoord 4, autoriteit 7%

Ik zou SimpleDateFormat gebruiken. Corrigeer me maar als er een makkelijkere manier is om een ​​maandkalender te maken, ik doe dit nu in code en ik weet het niet zo zeker.

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());
}

Antwoord 5, autoriteit 6%

Hier is hoe ik het zou doen. Ik laat de bereikcontrole van de int monthaan jou over.

import java.text.DateFormatSymbols;
public String formatMonth(int month, Locale locale) {
    DateFormatSymbols symbols = new DateFormatSymbols(locale);
    String[] monthNames = symbols.getMonths();
    return monthNames[month - 1];
}

Antwoord 6, autoriteit 5%

SimpleDateFormat gebruiken.

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"); 

Resultaat: februari


Antwoord 7, autoriteit 4%

Blijkbaar zit er in Android 2.2 een bug in SimpleDateFormat.

Om maandnamen te gebruiken, moet u ze zelf definiëren in uw bronnen:

<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>

En gebruik ze dan als volgt in je code:

/**
 * 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;
}

Antwoord 8, autoriteit 3%

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

Veel gemakkelijker om nu te doen in de java.time-klassen die deze lastige oude verouderde datum-tijd-klassen vervangen.

De Monthenum definieert een dozijn objecten, één voor elke maand.

De maanden zijn genummerd van 1-12 voor januari-december.

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

Vraag het object om een ​​string te genereren met de naam van de maand, automatisch gelokaliseerd.

Pas de TextStyleom aan te geven hoe lang of afgekort je de naam wilt hebben. Houd er rekening mee dat in sommige talen (niet Engels) de naam van de maand varieert als deze alleen of als onderdeel van een volledige datum wordt gebruikt. Elke tekststijl heeft dus een …_STANDALONEvariant.

Geef een Localeom te bepalen:

  • Welke menselijke taal moet bij de vertaling worden gebruikt.
  • Welke culturele normen moeten beslissen over zaken als afkortingen, interpunctie en hoofdletters.

Voorbeeld:

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

Naam → Monthobject

Ter info, in de andere richting gaan (het ontleden van een tekenreeks voor de naam van de maand om een ​​Monthenum-object te krijgen) is niet ingebouwd. Je zou je eigen klas kunnen schrijven om dit te doen. Hier is mijn snelle poging tot zo’n klasse. Gebruik op eigen risico. Ik heb deze code niet serieus overwogen en ook niet serieus getest.

Gebruik.

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." );
        }
    }
}

Over java.time

De java.time framework is ingebouwd in Java 8 en hoger. Deze klassen vervangen de lastige oude legacydatum-tijdklassen zoals java.util.Date, Calendar, &amp ; SimpleDateFormat.

Het Joda-Time-project, nu in onderhoudsmodus, adviseert migratie naar de java.timeklassen.

Zie voor meer informatie de Oracle-zelfstudie. En zoek Stack Overflow voor veel voorbeelden en uitleg. Specificatie is JSR 310.

U kunt java.timeobjecten rechtstreeks uitwisselen met uw database. Gebruik een JDBC-stuurprogrammadat voldoet aan JDBC 4.2of hoger. Geen strings nodig, geen java.sql.*klassen.

Waar zijn de java.time-klassen te verkrijgen?

  • Java SE 8, Java SE 9en hoger
    • Ingebouwd.
    • Onderdeel van de standaard Java API met een gebundelde implementatie.
    • Java 9 voegt enkele kleine functies en reparaties toe.
  • Java SE 6en Java SE 7
    • Veel van de java.time-functionaliteit is teruggekoppeld naar Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Latere versies van Android-bundelimplementaties van de java.time-klassen.
    • Voor eerdere Android (<26), de ThreeTenABPproject past ThreeTen-Backportaan (hierboven vermeld). Zie ThreeTenABP gebruiken….

Het ThreeTen-Extra-project verlengt java.time met extra lessen. Dit project is een proeftuin voor mogelijke toekomstige toevoegingen aan java.time. Mogelijk vindt u hier enkele nuttige klassen, zoals Interval, YearWeek, YearQuarteren meer.


Antwoord 9

Er is een probleem wanneer u de klasse DateFormatSymbols gebruikt voor de methode getMonthName om Month by Name op te halen en Month by Number te tonen op sommige Android-apparaten. Ik heb dit probleem als volgt opgelost:

In 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>

In de Java-klasse roept u deze array op deze manier aan:

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);
            }

Veel plezier met coderen 🙂


Antwoord 10

Kotlin-extensie

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

Gebruik

calendar.get(Calendar.MONTH).toMonthName()

Antwoord 11

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

Antwoord 12

Gewoon de regel invoegen

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

zal het lukken.


Antwoord 13

Probeer dit op een heel eenvoudige manier te gebruiken en noem het je eigen functie

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;
     }

Other episodes