ฉันจะแปลงจำนวนเต็มเป็นชื่อเดือนที่แปลเป็นภาษา Java ได้อย่างไร


101

ฉันได้รับจำนวนเต็มและฉันต้องการแปลงเป็นชื่อเดือนในภาษาต่างๆ:

ตัวอย่างภาษา en-us:
1 ->
2 มกราคม-> กุมภาพันธ์

ตัวอย่างภาษา es-mx:
1 -> Enero
2 -> Febrero


5
ระวังเดือน Java เป็นศูนย์ดังนั้น 0 = ม.ค. , 1 = ก.พ. ฯลฯ
Nick Holt

คุณพูดถูกดังนั้นหากจำเป็นต้องเปลี่ยนภาษาเพียงแค่ต้องเปลี่ยนสถานที่ ขอบคุณ
atomsfat

2
อัปเดต @NickHolt The modern java.timeMonthenum คือ 1-12 สำหรับเดือนมกราคม - ธันวาคม Ditto สำหรับ [ 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 Calendar` มีรูปแบบการกำหนดหมายเลขที่บ้าคลั่ง หนึ่งในหลาย ๆ เหตุผลที่ควรหลีกเลี่ยงคลาสดั้งเดิมตอนนี้ถูกแทนที่ด้วยคลาสjava.timeทั้งหมด
Basil Bourque

คำตอบ:


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

12
คุณไม่ต้องการ 'month-1' เนื่องจากอาร์เรย์เป็นศูนย์หรือไม่? atomsfat ต้องการ 1 -> มกราคมเป็นต้น
Brian Agnew

7
เขาต้องการเดือน -1 เพราะเดือนเป็นตัวเลข 1 เดือนที่ต้องแปลงเป็นตำแหน่งอาร์เรย์ที่เป็นศูนย์
Sam Barnum

5
สาธารณะ String getMonth (int month, Locale locale) {return DateFormatSymbols.getInstance (locale) .getMonths () [month-1]; }
atomsfat

4
เขาmonth-1ต้องการ ใคร ๆ ก็ใช้Calendar.get(Calendar.MONTH)ก็ต้องmonth
รอน

1
การปรับใช้ DateFormatSymbols ใน JDK 8 ดังนั้นเมธอด getMonths จึงไม่ส่งคืนค่าที่ถูกต้องสำหรับ Locale ทั้งหมดอีกต่อไป: oracle.com/technetwork/java/javase/…
ahaaman

33

คุณต้องใช้ LLLL สำหรับชื่อเดือนแบบสแตนด์อะโลน สิ่งนี้ถูกบันทึกไว้ในSimpleDateFormatเอกสารประกอบเช่น:

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

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

27

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 (หรือ 1.7 & 1.6 พร้อมThreeTen-Backport ) คุณสามารถใช้สิ่งนี้:

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

โปรดทราบว่าintegerMonthเป็นแบบ 1 ตามคือ 1 สำหรับเดือนมกราคม ช่วงคือ 1-12 เสมอสำหรับเดือนมกราคม - ธันวาคม (เช่นปฏิทินเกรกอเรียนเท่านั้น)


สมมติว่าคุณมี String Month ของเดือนพฤษภาคมเป็นภาษาฝรั่งเศสโดยใช้วิธีที่คุณโพสต์ (พฤษภาคมในภาษาฝรั่งเศสคือ Mai) ฉันจะรับหมายเลข 5 จาก String นี้ได้อย่างไร ??
58

@usertest ฉันเขียนคลาสร่างคร่าวๆMonthDelocalizerในคำตอบของฉันเพื่อรับMonthวัตถุจากสตริงชื่อเดือนที่ผ่านการแปล: mai→ Month.MAY โปรดทราบว่าเรื่องคดีความไว: ในฝรั่งเศสไม่ถูกต้องและควรจะMai mai
Basil Bourque

ปี 2019 นี่ไม่ใช่คำตอบยอดนิยมได้อย่างไร
anothernode

16

ฉันจะใช้ SimpleDateFormat มีคนช่วยแก้ไขให้ฉันถ้ามีวิธีที่ง่ายกว่าในการสร้างปฏิทินแบบเดือนฉันทำในรหัสตอนนี้และฉันก็ไม่แน่ใจ

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

คลาสที่น่ากลัวเหล่านี้เป็นมรดกตกทอดโดยคลาสjava.timeสมัยใหม่ที่กำหนดไว้ใน JSR 310 ทั้งหมด
Basil Bourque

14

นี่คือวิธีที่ฉันจะทำ ฉันจะปล่อยให้ช่วงการตรวจสอบ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];
}

12

ใช้ 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"); 

ผล: กุมภาพันธ์


7

เห็นได้ชัดว่าใน Android 2.2 มีข้อผิดพลาดกับ SimpleDateFormat

ในการใช้ชื่อเดือนคุณต้องกำหนดด้วยตนเองในแหล่งข้อมูลของคุณ:

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

จากนั้นใช้ในโค้ดของคุณดังนี้:

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

"เห็นได้ชัดว่าใน Android 2.2 มีข้อบกพร่อง" - จะมีประโยชน์หากคุณสามารถเชื่อมโยงไปยังตำแหน่งที่ติดตามข้อบกพร่องได้
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

ตอนนี้ทำได้ง่ายกว่ามากในคลาส java.time ที่เข้ามาแทนที่คลาสวันที่และเวลาดั้งเดิมที่ยุ่งยากเหล่านี้

Monthenum กำหนดวัตถุโหลหนึ่งสำหรับแต่ละเดือน

เดือนจะมีเลข 1-12 สำหรับมกราคม - ธันวาคม

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

สอบถามวัตถุเพื่อสร้าง String ของที่ชื่อของเดือนที่มีการแปลโดยอัตโนมัติ

ปรับTextStyleเพื่อระบุความยาวหรือตัวย่อที่คุณต้องการให้ชื่อ โปรดทราบว่าในบางภาษา (ไม่ใช่ภาษาอังกฤษ) ชื่อเดือนจะแตกต่างกันไปหากใช้เพียงอย่างเดียวหรือเป็นส่วนหนึ่งของวันที่ที่สมบูรณ์ ลักษณะข้อความแต่ละแบบจึงมีความ…_STANDALONEแตกต่างกัน

ระบุLocaleเพื่อตรวจสอบ:

  • ภาษามนุษย์ใดที่ควรใช้ในการแปล
  • บรรทัดฐานทางวัฒนธรรมใดที่ควรตัดสินประเด็นต่างๆเช่นการย่อเครื่องหมายวรรคตอนและการใช้อักษรตัวพิมพ์ใหญ่

ตัวอย่าง:

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

ชื่อ→ Monthวัตถุ

FYI ไปทิศทางอื่น (การแยกวิเคราะห์สตริงชื่อเดือนเพื่อรับMonthอ็อบเจ็กต์ enum) ไม่ได้อยู่ในตัว คุณสามารถเขียนชั้นเรียนของคุณเองได้ นี่คือความพยายามอย่างรวดเร็วของฉันในชั้นเรียนดังกล่าว ใช้ความเสี่ยงของคุณเองการใช้งานที่มีความเสี่ยงของคุณเองฉันไม่ได้ให้รหัสนี้โดยไม่มีความคิดที่จริงจังหรือการทดสอบอย่างจริงจังใด ๆ

การใช้งาน.

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

รหัส.

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

เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, และCalendarSimpleDateFormat

โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำให้ย้ายไปที่คลาสjava.time

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย ข้อมูลจำเพาะคือJSR 310310

คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่ต้องมีสตริงไม่ต้องมีjava.sql.*คลาส

จะหาคลาส java.time ได้ที่ไหน?

  • Java SE 8 , Java SE 9และใหม่กว่า
    • ในตัว.
    • ส่วนหนึ่งของ Java API มาตรฐานพร้อมการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android
    • การติดตั้งบันเดิล Android เวอร์ชันที่ใหม่กว่าของคลาส java.time
    • สำหรับก่อนหน้านี้ Android (<26) ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีใช้ ThreeTenABP … .

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โปรเจ็กต์นี้เป็นพื้นที่พิสูจน์สำหรับการเพิ่ม java.time ในอนาคต คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


1

มีปัญหาเมื่อคุณใช้คลาส DateFormatSymbols สำหรับเมธอด getMonthName เพื่อรับ Month by Name ซึ่งจะแสดง Month by Number ในอุปกรณ์ Android บางรุ่น ฉันได้แก้ไขปัญหานี้แล้วโดยทำวิธีนี้:

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

ในคลาส Java เพียงแค่เรียกอาร์เรย์นี้ในลักษณะนี้:

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

            }

Happy Coding :)


1

Kotlin ส่วนขยาย

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

การใช้งาน

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

Calendarคลาสที่น่ากลัวถูกแทนที่เมื่อหลายปีก่อนโดยคลาสjava.time ที่กำหนดไว้ใน JSR 310
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()));
}

ดูเหมือนจะเป็นคำตอบที่เหมาะสม แต่คุณอธิบายได้ไหมว่าคุณทำอะไรและทำไมคุณถึงทำเช่นนี้
Martin Frank

ฉันทำแบบนี้เพราะคิดว่าง่ายและไม่ซับซ้อน!
Diogo Oliveira

แม้ว่าจะใช้SimpleDateFormatคลาสที่ล้าสมัยและน่าเบื่อหน่ายมานาน
Ole VV

คลาสวันเวลาที่น่ากลัวเหล่านี้ถูกแทนที่เมื่อหลายปีก่อนโดยคลาสjava.time ที่กำหนดไว้ใน JSR 310
Basil Bourque

0

เพียงแค่ใส่เส้น

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

จะทำเคล็ดลับ


2
DateFormatSymbolsเป็นส่วนหนึ่งของการเรียนที่น่ากลัววันเวลาว่าตอนนี้มีมรดกเป็นของการยอมรับของJSR 310 ตอนนี้แทนที่ด้วยคลาสjava.time การแนะนำให้ใช้ในปี 2019 เป็นคำแนะนำที่ไม่ดี
Basil Bourque

คำตอบนี้ซ้ำเนื้อหาของคำตอบที่ได้รับการยอมรับ
Basil Bourque

0

ลองใช้วิธีนี้ง่ายมากและเรียกมันว่า func ของคุณเอง

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
ไม่จำเป็นต้องเขียนโค้ดแบบนี้ Java มีในMonth::getDisplayNameตัว
Basil Bourque

ไม่จำเป็นต้องเขียนโค้ดสำเร็จรูปนี้ ตรวจสอบคำตอบของฉันที่โพสต์ไว้ด้านบน
Sadda Hussain
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.