Java'da bir Tamsayıyı yerelleştirilmiş ay adına nasıl dönüştürebilirim?


99

Bir tam sayı alıyorum ve çeşitli yerel ayarlarda ay adlarına dönüştürmem gerekiyor:

En-us yerel ayarı örneği:
1 ->
2 Ocak -> Şubat

Es-mx yerel ayarı örneği:
1 -> Enero
2 -> Febrero


5
Dikkat edin, Java ayları sıfır tabanlıdır, yani 0 = Oca, 1 = Şub, vb.
Nick Holt

haklısınız, bu yüzden dili değiştirmeniz gerekirse, sadece yerel ayarı değiştirmeniz yeterlidir. Teşekkürler
atomsfat

2
@NickHolt GÜNCELLEME Modern java.timeMonthenum tek tabanlıdır: Ocak-Aralık için 1-12. [Takvim` için aynen java.time.DayOfWeek](https://docs.oracle.com/javase/9/docs/api/java/time/DayOfWeek.html): 1-7 for Monday-Sunday per ISO 8601 standard. Only the troublesome old legacy date-time classes such as çılgın numaralandırma şemaları vardır. Eski sınıflardan kaçınmanın birçok nedeninden biri , şimdi tamamen java.time sınıfları tarafından değiştirildi .
Basil Bourque

Yanıtlar:


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

12
Dizi sıfır tabanlı olduğundan 'ay-1'e ihtiyacınız yok mu? atomsfat 1 -> Ocak vb. istiyor
Brian Agnew

7
1. aya ihtiyacı var, çünkü ay, sıfır tabanlı dizi konumuna dönüştürülmesi gereken 1 tabanlı ay sayısıdır
Sam Barnum

5
public String getMonth (int ay, Yerel ayar) {return DateFormatSymbols.getInstance (yerel ayar) .getMonths () [ay-1]; }
atomsfat

4
O ihtiyacı var month-1. Kullanan başka Calendar.get(Calendar.MONTH)month
Ron

1
DateFormatSymbols uygulaması JDK 8'de değiştirildi, bu nedenle getMonths yöntemi artık tüm
Locale'ler

33

Bağımsız ay isimleri için LLLL kullanmanız gerekir. bu SimpleDateFormat, aşağıdaki gibi belgelerde belgelenmiştir:

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

JDK 1.7 /IllegalArgumentException : Illegal pattern character 'L'
AntJavaDev

26

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

Java 1.8'den (veya ThreeTen-Backport ile 1.7 & 1.6 ) beri bunu kullanabilirsiniz:

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

Not integerMonth1 tabanlı olduğu 1 Ocak içindir yani. Aralık, Ocak-Aralık için her zaman 1'den 12'ye kadardır (yani yalnızca Miladi takvim).


Diyelim ki yayınladığınız yöntemi kullanarak Fransızca Mayıs ayınız var (Fransızca Mayıs Mai), bu String'den 5 sayısını nasıl alabilirim?
usertest

@usertest Bir kaba taslak sınıfı yazdım MonthDelocalizeriçinde benim Yanıt de zaten ona Month: Bir geçirilen yerelleştirilmiş ay adı dizesinden nesneyi maiMonth.MAY →. Büyük / küçük harfe duyarlılığın önemli olduğunu unutmayın: Fransızca'da Maigeçersizdir ve olmalıdır mai.
Basil Bourque

Yıl 2019. Nasıl en iyi cevap bu değil?
başkanode

16

SimpleDateFormat kullanırdım. Aylık takvim yapmanın daha kolay bir yolu varsa biri beni düzeltir, bunu şimdi kodla yapıyorum ve o kadar emin değilim.

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

Bu korkunç sınıflar artık mirastır ve yerini tamamen JSR 310'da tanımlanan modern java.time sınıfları almıştır.
Basil Bourque

14

İşte bunu nasıl yapacağım. Size int monthkadar menzil kontrolü bırakacağım .

import java.text.DateFormatSymbols;

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

12

SimpleDateFormat kullanarak.

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

Sonuç: Şubat


7

Görünüşe göre Android 2.2'de SimpleDateFormat ile ilgili bir hata var.

Ay adlarını kullanmak için, bunları kaynaklarınızda kendiniz tanımlamanız gerekir:

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

Ve sonra bunları kodunuzda şu şekilde kullanın:

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

"Görünüşe göre Android 2.2'de bir hata var" - Hatanın izlendiği yere bağlantı kurmanız faydalı olacaktır.
Peter Hall

6

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

Bu zahmetli eski tarih-saat sınıflarının yerini alan java.time sınıflarında şimdi yapmak çok daha kolay.

MonthEnum bir düzine nesneleri, her bir ay için bir tane tanımlar.

Ocak-Aralık ayları 1-12 arasıdır.

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

Nesneden bir String oluşturmasını isteyin. , otomatik olarak yerelleştirilmiş, ayın adı .

Ayarlayın TextStyleAdı ne kadar uzun veya kısaltmak istediğinizi belirtmek için . Bazı dillerde (İngilizce değil), ay adının tek başına veya tam bir tarihin parçası olarak kullanıldığında değiştiğini unutmayın. Yani her metin stilinin bir …_STANDALONEçeşidi vardır.

Bir belirtin Locale :

  • Çeviride hangi insan dili kullanılmalıdır.
  • Kısaltma, noktalama işaretleri ve büyük harf kullanımı gibi konulara hangi kültürel normlar karar vermelidir.

Misal:

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

İsim → Month nesne

Bilginize, diğer yöne gitmek (bir Monthenum nesnesi elde etmek için ayın adı dizesini ayrıştırmak ) yerleşik değildir. Bunu yapmak için kendi sınıfınızı yazabilirsiniz. İşte böyle bir sınıftaki hızlı girişimim.Kendi sorumluluğunuzda kullanın . Bu kodu ne ciddi düşündüm ne de ciddi bir test ettim.

Kullanım.

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

Kod.

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

Hakkında java.time

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar&SimpleDateFormat .

Şu anda bakım modunda olan Joda-Time projesi, java.time sınıflarına geçişi önerir .

Daha fazla bilgi edinmek için Oracle Eğitimi'ne bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310 .

Java.time nesnelerini doğrudan veritabanınız ile değiş tokuş edebilirsiniz . JDBC 4.2 veya üstü ile uyumlu bir JDBC sürücüsü kullanın . Dizelere gerek yok, derslere gerek yok .java.sql.*

Java.time sınıflarını nereden edinebilirim?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time uygulamasına gelecekteki olası eklemeler için kanıtlayıcı bir zemindir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


1

GetMonthName yöntemi için DateFormatSymbols sınıfını kullandığınızda, bazı Android cihazlarda Aya Göre Ay'ı göstermesi için Aya Göre Ay'ı gösterdiğinizde bir sorun vardır. Bu sorunu şu şekilde çözdüm:

String_array.xml'de

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

Java sınıfında bu diziyi şu şekilde çağırın:

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

            }

Mutlu Kodlama :)


1

Kotlin Uzantısı

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

Kullanım

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

Korkunç Calendarsınıfın yerini yıllar önce JSR 310'da tanımlanan java.time sınıfları aldı.
Basil Bourque

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

bu doğru bir cevap gibi görünüyor, ancak ne yaptığınızı ve neden bu şekilde yaptığınızı açıklayabilir misiniz?
Martin Frank

Bu şekilde yapıyorum çünkü bence basit ve karmaşık değil!
Diogo Oliveira

Yine de, kötü şöhretli zahmetli ve modası geçmiş SimpleDateFormatsınıfı kullanıyor.
Ole VV

Bu korkunç tarih-saat sınıflarının yerini yıllar önce JSR 310'da tanımlanan java.time sınıfları aldı.
Basil Bourque


0

Bunu çok basit bir şekilde kullanmaya çalışın ve ona kendi işiniz gibi hitap edin

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

1
Bu tür bir kod yazmaya gerek yok. Java yerleşiktir Month::getDisplayName.
Basil Bourque

Bu standart kodu yazmaya gerek yok. Yukarıda yayınlanan cevabımı kontrol edin.
Sadda Hussain
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.