ชื่อเดือนเป็นสตริง


90

ฉันพยายามคืนชื่อของเดือนเป็น String เช่น "พฤษภาคม" "กันยายน" "พฤศจิกายน"

ฉันเหนื่อย:

int month = c.get(Calendar.MONTH);

อย่างไรก็ตามสิ่งนี้จะคืนค่าจำนวนเต็ม (5, 9, 11, ตามลำดับ) ฉันจะได้รับชื่อเดือน?

คำตอบ:


88

ใช้getDisplayName

สำหรับการใช้งาน API ก่อนหน้านี้ String.format(Locale.US,"%tB",c);


ฉันพบปัญหา: getDisplayName (month, Calendar.LONG, Locale.US) และ Eclipse กำลังบอกฉันว่า Calendar.LONG หรือ Calendar.SHORT ไม่มีอยู่
Gaby

ที่แปลกมาก คุณกำลังใช้java.util.Calendarและไม่ใช่Calendarคลาสอื่นใช่ไหม
จริง

ใช่. ดูเหมือนว่า getDisplayName () และ Calendar.LONG และ Calendar.SHORT เป็น API ระดับ 9 เท่านั้น ดังนั้นมันใช้ได้กับระดับ 9 แต่ฉันต้องการระดับ 7 :(
Gaby

3
Formatter f = new Formatter();(คุณสามารถตั้งชื่อภาษาให้เป็นทางเลือกก็ได้) จากนั้นString monthName = f.format("%tB",c).toString();หรือ%tbสำหรับชื่อย่อ
จริง

5
ยังใช้ Locale.getDefault () แทน Locale.US อาจเป็นความคิดที่ดี :)
Shine

163

ใช้สิ่งนี้:

Calendar cal=Calendar.getInstance();
SimpleDateFormat month_date = new SimpleDateFormat("MMMM");
String month_name = month_date.format(cal.getTime());

ชื่อเดือนจะมีชื่อเต็มเดือนถ้าคุณต้องการชื่อเดือนแบบสั้นให้ใช้สิ่งนี้

 SimpleDateFormat month_date = new SimpleDateFormat("MMM");
 String month_name = month_date.format(cal.getTime());

13
"MMMM" ก็เพียงพอแล้วสำหรับกรณีแรก
yanchenko

119

สำหรับการรับเดือนในตัวแปรสตริงให้ใช้รหัสด้านล่าง

ตัวอย่างเช่นเดือนกันยายน:

M -> 9

MM -> 09

MMM -> ก.ย.

MMMM -> กันยายน

String monthname=(String)android.text.format.DateFormat.format("MMMM", new Date())

1
ใช่ขอบคุณมันทำงานได้อย่างมีเสน่ห์ในทุกภาษาที่ฉันใช้ (ฝรั่งเศสอังกฤษเยอรมัน)
Chrysotribax

46

"MMMM" ไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง (แม้ว่าจะใช้ได้กับหลายภาษา) ให้ใช้รูปแบบ "LLLL" กับ SimpleDateFormat

เพิ่มการรองรับ 'L' เป็นส่วนขยายที่เข้ากันได้กับ ICU สำหรับชื่อเดือนแบบสแตนด์อะโลนในแพลตฟอร์ม Android เมื่อมิถุนายน 20102010

แม้ว่าในภาษาอังกฤษจะไม่มีความแตกต่างระหว่างการเข้ารหัสโดย "MMMM" และ "LLLL" แต่คุณควรคำนึงถึงภาษาอื่นด้วย

เช่นนี่คือสิ่งที่คุณจะได้รับหากคุณใช้Calendar.getDisplayNameหรือรูปแบบ "MMMM" สำหรับเดือนมกราคมกับภาษารัสเซียLocale:

января (ซึ่งถูกต้องสำหรับสตริงวันที่ที่สมบูรณ์: " 10 января, 2014 ")

แต่ในกรณีของชื่อเดือนแบบสแตนด์อะโลนคุณจะคาดหวัง:

январь

ทางออกที่เหมาะสมคือ:

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

หากคุณสนใจว่าคำแปลทั้งหมดมาจากไหน - นี่คือการอ้างอิงถึงการแปลปฏิทินเกรกอเรียน (ปฏิทินอื่น ๆ ที่เชื่อมโยงอยู่ที่ด้านบนของหน้า)


1
'LLLL' มีให้ใช้งานตั้งแต่ Java 8 เท่านั้นคุณสามารถใช้ 'MMMM' กับ SimpleDateFormat และทำงานได้ดีอย่างสมบูรณ์แบบสำหรับเวอร์ชันสแตนด์อโลนเช่นกัน
juanheyns

เพื่อความชัดเจนในภาษารัสเซียคำแปลของ "Января" คือกรณีสัมพันธการกซึ่งหมายถึง "ของเดือนมกราคม" ในขณะที่ "Январь" เป็นชื่อที่มีความหมายเพียงแค่ "มกราคม" อาจมีภาษาสลาฟอื่น ๆ ที่มีความแตกต่างเช่นยูเครนและเซอร์เบีย เป็นเพียงไวยากรณ์และมักจะไม่สำคัญเกินไป แต่กรณีการใช้งานที่ให้ไว้ในคำตอบนี้ถูกต้องตามหลักไวยากรณ์: ใช้ MMMM สำหรับวันที่ที่สมบูรณ์และ LLLL เมื่อแสดงเดือนด้วยตัวเองหากคุณต้องการให้ถูกต้องที่สุด
moonlightcheese

ขอบคุณฉันกำลังดิ้นรนกับคดีภาษารัสเซีย :)
BekaBot

26

ง่ายๆเพียงเท่านี้

mCalendar = Calendar.getInstance();    
String month = mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());

Calendar.LONG คือการรับชื่อเต็มของเดือนและ Calendar.SHORT ให้ชื่อสั้น ๆ ตัวอย่างเช่น Calendar.LONG จะส่งคืนปฏิทินมกราคม SHORT จะส่งคืนมกราคม


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

10

ฉันเก็บคำตอบนี้ไว้ซึ่งมีประโยชน์สำหรับกรณีอื่น ๆ แต่คำตอบ @trutheality ดูเหมือนจะเป็นวิธีที่ง่ายและตรงที่สุด

คุณสามารถใช้DateFormatSymbols

DateFormatSymbols(Locale.FRENCH).getMonths()[month]; // FRENCH as an example

5

วิธีเดียวบน Android ในการจัดรูปแบบชื่อเดือนสแตนอโลนที่ถูกต้องสำหรับภาษาต่างๆเช่นยูเครนรัสเซียเช็ก

private String getMonthName(Calendar calendar, boolean short) {
    int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY | DateUtils.FORMAT_NO_YEAR;
    if (short) {
        flags |= DateUtils.FORMAT_ABBREV_MONTH;
    }
    return DateUtils.formatDateTime(getContext(), calendar.getTimeInMillis(), flags);
}

ทดสอบกับ API 15-25

ผลลัพธ์สำหรับเดือนพฤษภาคมคือМайแต่ไม่ใช่Мая


3

รัสเซีย.

Month
.MAY
.getDisplayName(
    TextStyle.FULL_STANDALONE ,
    new Locale( "ru" , "RU" )
)

май

ภาษาอังกฤษในสหรัฐอเมริกา

Month
.MAY
.getDisplayName(
    TextStyle.FULL_STANDALONE ,
    Locale.US
)

อาจ

ดูโค้ดนี้ได้ที่ IdeOne.comIdeOne.com

ThreeTenABP และ java.time

นี่คือคำตอบที่ทันสมัย เมื่อคำถามนี้ถูกถามในปี 2554 CalendarและGregorianCalendarมักใช้สำหรับวันที่และเวลาแม้ว่าจะออกแบบมาไม่ดีก็ตาม เมื่อ 8 ปีที่แล้วและชั้นเรียนเหล่านั้นล้าสมัยไปนานแล้ว สมมติว่าคุณยังไม่ได้ใช้ API ระดับ 26 ข้อเสนอแนะของฉันคือใช้ไลบรารี ThreeTenABP ซึ่งมีแบ็คพอร์ตของ java.time ที่ปรับใช้กับ Android ซึ่งเป็นวันที่และเวลาของ Java API ที่ทันสมัย java.time ดีกว่ามากในการทำงานด้วย

ขึ้นอยู่กับความต้องการและสถานการณ์ที่แท้จริงของคุณมีสองทางเลือก:

  1. ใช้MonthและgetDisplayNameวิธีการ
  2. ใช้ไฟล์DateTimeFormatter.

ใช้เดือน

    Locale desiredLanguage = Locale.ENGLISH;
    Month m = Month.MAY;
    String monthName = m.getDisplayName(TextStyle.FULL, desiredLanguage);
    System.out.println(monthName);

ผลลัพธ์จากตัวอย่างข้อมูลนี้คือ:

อาจ

ในไม่กี่ภาษามันจะสร้างความแตกต่างว่าคุณจะใช้หรือTextStyle.FULL TextStyle.FULL_STANDALONEคุณจะต้องดูอาจตรวจสอบกับผู้ใช้ของคุณว่าทั้งสองแบบใดเหมาะกับบริบทของคุณ

ใช้ DateTimeFormatter

หากคุณมีหรือไม่มีช่วงเวลาของวันฉันพบว่ามีDateTimeFormatterประโยชน์มากขึ้น ตัวอย่างเช่น:

    DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", desiredLanguage);

    ZonedDateTime dateTime = ZonedDateTime.of(2019, 5, 31, 23, 49, 51, 0, ZoneId.of("America/Araguaina"));
    String monthName = dateTime.format(monthFormatter);

ฉันกำลังแสดงการใช้ a ZonedDateTimeซึ่งเป็นสิ่งทดแทนที่ใกล้เคียงที่สุดสำหรับCalendarคลาสเก่า รหัสดังกล่าวจะทำงานให้LocalDateเป็นLocalDateTime, MonthDay, OffsetDateTimeและYearMonthมากเกินไป

จะเกิดอะไรขึ้นถ้าคุณได้รับCalendarจาก API เดิมที่ยังไม่ได้อัปเกรดเป็น java.time แปลงเป็น a ZonedDateTimeและดำเนินการตามด้านบน:

    Calendar c = getCalendarFromLegacyApi();
    ZonedDateTime dateTime = DateTimeUtils.toZonedDateTime(c);

ส่วนที่เหลือก็เหมือนเดิม

คำถาม: java.time ไม่ต้องการ Android API ระดับ 26 ใช่หรือไม่

java.time ทำงานได้ดีบนอุปกรณ์ Android ทั้งรุ่นเก่าและรุ่นใหม่ มันก็ต้องมีอย่างน้อยJava 6

  • ใน Java 8 ขึ้นไปและบนอุปกรณ์ Android รุ่นใหม่ ๆ (จาก API ระดับ 26) API ที่ทันสมัยมาในตัว
  • ใน Java 6 และ 7 ที่ไม่ใช่ Android จะได้รับ ThreeTen Backport ซึ่งเป็นแบ็คพอร์ตของคลาสสมัยใหม่ (ThreeTen สำหรับ JSR 310 ดูลิงก์ที่ด้านล่าง)
  • บน Android (รุ่นเก่ากว่า) ใช้ ThreeTen Backport รุ่น Android เรียกว่า ThreeTenABP และตรวจสอบให้แน่ใจว่าคุณนำเข้าคลาสวันที่และเวลาจากorg.threeten.bpแพคเกจย่อย

ลิงค์


2

ฉันอยากจะแนะนำให้ใช้Calendarobject และLocaleเนื่องจากชื่อเดือนแตกต่างกันสำหรับภาษาต่างๆ:

// index can be 0 - 11
private String getMonthName(final int index, final Locale locale, final boolean shortName)
{
    String format = "%tB";

    if (shortName)
        format = "%tb";

    Calendar calendar = Calendar.getInstance(locale);
    calendar.set(Calendar.MONTH, index);
    calendar.set(Calendar.DAY_OF_MONTH, 1);

    return String.format(locale, format, calendar);
}

ตัวอย่างชื่อเดือนเต็ม:

System.out.println(getMonthName(0, Locale.US, false));

ผลลัพธ์: January

ตัวอย่างชื่อเดือนแบบสั้น:

System.out.println(getMonthName(0, Locale.US, true));

ผลลัพธ์: Jan


2

ตัวอย่างวิธีรับวันที่และเวลาในรูปแบบ "2018 พ.ย. 01 16:18:22" ให้ใช้สิ่งนี้

DateFormat dateFormat = new SimpleDateFormat("yyyy MMM dd HH:mm:ss");
        Date date = new Date();
         dateFormat.format(date);

0

การตั้งชื่อเดือนแบบสแตนด์อโลนเป็นเรื่องยากที่จะดำเนินการอย่าง "ถูกต้อง" ใน Java (อย่างน้อยในการเขียนนี้ฉันกำลังใช้ Java 8 อยู่)

ปัญหาคือในบางภาษารวมถึงรัสเซียและเช็กชื่อเดือนเวอร์ชันสแตนด์อโลนจะแตกต่างจากเวอร์ชัน "การจัดรูปแบบ" นอกจากนี้ดูเหมือนว่าไม่มี Java API เดียวที่จะให้สตริงที่ "ดีที่สุด" แก่คุณ คำตอบส่วนใหญ่ที่โพสต์ไว้ที่นี่มีเฉพาะเวอร์ชันการจัดรูปแบบเท่านั้น วางด้านล่างเป็นวิธีแก้ปัญหาในการรับชื่อเดือนเดียวเวอร์ชันสแตนด์อโลนหรือรับอาร์เรย์พร้อมกับทั้งหมด

ฉันหวังว่านี่จะช่วยคนอื่นได้บ้าง!

/**
 * getStandaloneMonthName, This returns a standalone month name for the specified month, in the
 * specified locale. In some languages, including Russian and Czech, the standalone version of
 * the month name is different from the version of the month name you would use as part of a
 * full date. (Different from the formatting version).
 *
 * This tries to get the standalone version first. If no mapping is found for a standalone
 * version (Presumably because the supplied language has no standalone version), then this will
 * return the formatting version of the month name.
 */
private static String getStandaloneMonthName(Month month, Locale locale, boolean capitalize) {
    // Attempt to get the standalone version of the month name.
    String monthName = month.getDisplayName(TextStyle.FULL_STANDALONE, locale);
    String monthNumber = "" + month.getValue();
    // If no mapping was found, then get the formatting version of the month name.
    if (monthName.equals(monthNumber)) {
        DateFormatSymbols dateSymbols = DateFormatSymbols.getInstance(locale);
        monthName = dateSymbols.getMonths()[month.getValue()];
    }
    // If needed, capitalize the month name.
    if ((capitalize) && (monthName != null) && (monthName.length() > 0)) {
        monthName = monthName.substring(0, 1).toUpperCase(locale) + monthName.substring(1);
    }
    return monthName;
}

/**
 * getStandaloneMonthNames, This returns an array with the standalone version of the full month
 * names.
 */
private static String[] getStandaloneMonthNames(Locale locale, boolean capitalize) {
    Month[] monthEnums = Month.values();
    ArrayList<String> monthNamesArrayList = new ArrayList<>();
    for (Month monthEnum : monthEnums) {
        monthNamesArrayList.add(getStandaloneMonthName(monthEnum, locale, capitalize));
    }
    // Convert the arraylist to a string array, and return the array.
    String[] monthNames = monthNamesArrayList.toArray(new String[]{});
    return monthNames;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.