2009-06-24 11 views
80

ottengo un numero intero e ho bisogno di convertire in nomi dei mesi in varie località:Come posso convertire un intero in un nome di mese localizzato in Java?

Esempio per locale en-us:
1 -> Gennaio
2 -> Febbraio

Esempio per es impostazioni internazionali -mx:
1 -> Enero
2 -> Febrero

+3

Attenzione, mesi Java sono a base zero in modo da 0 = gennaio, 1 = febbraio, ecc –

+0

hai ragione, quindi, se la necessità di cambiare la lingua, solo bisogno di cambiare le impostazioni internazionali. Grazie – atomsfat

+0

@NickHolt ** AGGIORNAMENTO ** Il moderno ['java.timeMonth'] (https://docs.oracle.com/javase/9/docs/api/java/time/Month.html) enum è basato su uno : 1-12 per gennaio-dicembre. Idem per ['java.time.DayOfWeek] (https://docs.oracle.com/javase/9/docs/api/java/time/DayOfWeek.html): 1-7 per lunedì-domenica secondo lo standard ISO 8601. Solo le fastidiose vecchie lezioni di data e ora come "Calendar" hanno schemi di numerazione pazzeschi. Uno dei tanti motivi per evitare le classi legacy, ora soppiantate interamente dalle classi * java.time *. –

risposta

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

Non hai bisogno di 'month-1', dato che l'array è a base zero? atomsfat vuole 1 -> gennaio ecc. –

+4

Ha bisogno del mese 1, perché il mese è il numero del mese 1 che deve essere convertito nella posizione dell'array a base zero –

+0

Anche questo funziona, è necessario costruire DateFormatSymbols con il locale comunque. – stevedbrown

14

userei SimpleDateFormat. Qualcuno mi corregga se c'è un modo più semplice per creare un calendario mensile, lo faccio ora nel codice e non ne sono così sicuro.

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

"MMMM" è sufficiente. –

13

Ecco come lo farei. Lascerò il controllo dei range su int month.

import java.text.DateFormatSymbols; 

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

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

Risultato: febbraio

5

A quanto pare in Android 2.2 c'è un bug con SimpleDateFormat.

Per poter utilizzare nomi di mese è necessario definire da soli nelle vostre risorse:

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

E poi utilizzarli nel codice come questo:

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

_ "Apparentemente in Android 2.2 c'è un bug" _ - Sarebbe utile se potessi collegarti a dove è stato tracciato il bug. –

26

È necessario utilizzare LLLL per nomi di mese autonomi. questo è documentato nella documentazione SimpleDateFormat, come ad esempio:

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

Grazie mille, amico. – antongorodezkiy

+0

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

7

java.time

Dal momento che Java 1.8 (o 1.7 & 1.6 con la ThreeTen-Backport) È possibile utilizzare questo:

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

Nota che integerMonth è 1, ovvero 1 è per gennaio. L'intervallo è sempre da 1 a 12 per gennaio-dicembre (cioè solo per il calendario gregoriano).

+0

diciamo che hai il mese della stringa di maggio in francese usando il metodo che hai postato (maggio in francese è Mai), come posso ottenere il numero 5 da questa stringa? ? – usertest

+0

@usertest Ho scritto una 'roughDelocalizer' di classe grezza in [my Answer] (https://stackoverflow.com/a/39220766/642706) per ottenere un oggetto' Month' da una stringa di nome mese localizzata passata: 'mai '→ Month.MAY. Nota che la case-sensitive è importante: in francese, 'Mai' non è valido e dovrebbe essere' mai'. –

1

C'è un problema quando si utilizza la classe DateFormatSymbols per il suo metodo getMonthName per ottenere Mese per nome mostra Mese per numero in alcuni dispositivi Android. Ho risolto questo problema in questo modo:

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 classe Java basta chiamare questo array come questo senso:

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

      } 

Felice Coding :)

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

sembra essere la risposta giusta, ma puoi spiegare cosa fai e perché lo fai in questo modo? –

+0

Lo faccio perché penso sia semplice e non complesso! –

2

tl; dr

Month.of(yourMonthNumber) 
    .getDisplayName( 
     TextStyle.SHORT_STANDALONE , 
     new Locale("es" , "MX") 
) 

java.time.Month

Molto più facile da fare ora nelle classi java.time che soppiantano queste fastidiose vecchie lezioni di data e ora legacy.

L'enum Month definisce una dozzina di oggetti, uno per ogni mese.

I mesi sono da 1 a 12 per gennaio-dicembre.

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

Chiedere all'oggetto di generare una stringa di name of the month, automatically localized.

Regolare TextStyle per specificare per quanto tempo o in modo abbreviato si desidera il nome. Nota che in alcune lingue (non in inglese) il nome del mese varia se usato da solo o come parte di una data completa. Quindi ogni stile di testo ha una variante …_STANDALONE.

Specificare un Locale per determinare:

  • Quale linguaggio umano deve essere utilizzata in una traduzione.
  • Quali norme culturali dovrebbero decidere questioni come abbreviazione, punteggiatura e maiuscole.

Esempio:

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

Nome → Month oggetto

FYI, andando nella direzione opposta (l'analisi di una stringa di nome-del-mese per ottenere un oggetto Month enum) non è built-in. Potresti scrivere la tua classe per farlo. Ecco il mio rapido tentativo in questa classe. Utilizzare a proprio rischio. Ho dato a questo codice nessun pensiero serio e nessun test serio.

Utilizzo.

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

Codice.

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

Chi java.time

Il quadro java.time è costruito in Java 8 e versioni successive. Queste classi soppiantano le fastidiose classi di data legacy come java.util.Date, Calendar, & SimpleDateFormat.

Il progetto Joda-Time, ora in maintenance mode, consiglia la migrazione alle classi java.time.

Per ulteriori informazioni, vedere Oracle Tutorial. E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310.

È possibile scambiare oggetti java.time direttamente con il database. Utilizzare un codice compatibile JDBC driver con JDBC 4.2 o successivo. Nessuna necessità di stringhe, nessuna necessità di classi java.sql.*.

Dove ottenere le classi java.time?

  • Java SE 8, Java SE 9, e più tardi
    • incorporato.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • Java SE 6 e Java SE 7
    • Molte delle funzionalità java.time è di back-porting per Java 6 .
  • Android
    • versioni successive di implementazioni fascio Android delle classi java.time.
    • Per Android precedente (< 26), il progetto ThreeTenABP si adatta a ThreeTen-Backport (menzionato sopra). Vedi How to use ThreeTenABP….

Il progetto ThreeTen-Extra java.time prolunga con classi aggiuntive. Questo progetto è un terreno di prova per possibili aggiunte future a java.time. È possibile trovare alcune classi utili come Interval, YearWeek, YearQuarter e more.

-1
private String returnMonthAsString(String month) {  
    if(month.equals("01")){ 
    return "January";  
    }else if(month.equals("02")){ 
     return "February"; 
    }else if(month.equals("03")){ 
     return "March"; 
    }else if(month.equals("04")){ 
     return "April"; 
    }else if(month.equals("05")){ 
     return "May"; 
    }else if(month.equals("06")){ 
     return "June"; 
    }else if(month.equals("07")){ 
     return "July"; 
    }else if(month.equals("08")){ 
     return "August"; 
    }else if(month.equals("09")){ 
     return "September"; 
    }else if(month.equals("10")){ 
     return "October"; 
    }else if(month.equals("11")){ 
     return "November"; 
    }else if(month.equals("12")){ 
     return "December"; 
    }else { 
     return null; 
    }   
} 
+0

non è affatto efficiente – Benjamin