如何在 Java 中将整数转换为本地化的月份名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1038570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I convert an Integer to localized month name in Java?
提问by atomsfat
I get an integer and I need to convert to a month names in various locales:
我得到一个整数,我需要在各种语言环境中转换为月份名称:
Example for locale en-us:
1 -> January
2 -> February
locale en-us 示例:
1 -> 一月
2 -> 二月
Example for locale es-mx:
1 -> Enero
2 -> Febrero
语言环境 es-mx 示例:
1 -> Enero
2 -> Febrero
采纳答案by joe
import java.text.DateFormatSymbols;
public String getMonth(int month) {
return new DateFormatSymbols().getMonths()[month-1];
}
回答by stevedbrown
I would use SimpleDateFormat. Someone correct me if there is an easier way to make a monthed calendar though, I do this in code now and I'm not so sure.
我会使用 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());
}
回答by Bill the Lizard
Here's how I would do it. I'll leave range checking on the int month
up to you.
这是我将如何做到的。我会把范围检查留给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];
}
回答by Terence
Using SimpleDateFormat.
使用 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");
Result: February
结果:二月
回答by IHeartAndroid
Apparently in Android 2.2 there is a bug with SimpleDateFormat.
显然,在 Android 2.2 中,SimpleDateFormat 存在一个错误。
In order to use month names you have to define them yourself in your resources:
为了使用月份名称,您必须自己在资源中定义它们:
<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>
And then use them in your code like this:
然后像这样在你的代码中使用它们:
/**
* 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;
}
回答by Ilya Lisway
You need to use LLLL for stand-alone month names. this is documented in the SimpleDateFormat
documentation, such as:
您需要将 LLLL 用于独立的月份名称。这在文档中SimpleDateFormat
记录,例如:
SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
dateFormat.format( date );
回答by Oliv
tl;dr
tl;博士
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
时间
Since Java 1.8 (or 1.7 & 1.6 with the ThreeTen-Backport) you can use this:
从 Java 1.8(或 1.7 & 1.6 with the ThreeTen-Backport)开始,您可以使用这个:
Month.of(integerMonth).getDisplayName(TextStyle.FULL_STANDALONE, locale);
Note that integerMonth
is 1-based, i.e. 1 is for January. Range is always from 1 to 12 for January-December (i.e. Gregorian calendar only).
请注意,它integerMonth
是基于 1 的,即 1 表示一月。1 月至 12 月的范围始终为 1 到 12(即仅限公历)。
回答by Faakhir
There is an issue when you use DateFormatSymbols class for its getMonthName method to get Month by Name it show Month by Number in some Android devices. I have resolved this issue by doing this way:
当您将 DateFormatSymbols 类用于其 getMonthName 方法以按名称获取月份时,会出现问题,它在某些 Android 设备中按数字显示月份。我通过这样做解决了这个问题:
In String_array.xml
在 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 Java class just call this array like this way:
在 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 :)
快乐编码:)
回答by Diogo Oliveira
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("MMMMM", new Locale("en", "US"));
System.out.println(format.format(new Date()));
}
回答by Basil Bourque
tl;dr
tl;博士
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.Month
Much easier to do now in the java.time classes that supplant these troublesome old legacy date-time classes.
现在在取代这些麻烦的旧日期时间类的 java.time 类中要容易得多。
The Month
enum defines a dozen objects, one for each month.
该Month
枚举定义了十几个对象,每月一。
The months are numbered 1-12 for January-December.
1 月至 12 月的月份编号为 1-12。
Month month = Month.of( 2 ); // 2 → February.
Ask the object to generate a String of the name of the month, automatically localized.
Adjust the TextStyle
to specify how long or abbreviated you want the name. Note that in some languages (not English) the month name varies if used alone or as part of a complete date. So each text style has a …_STANDALONE
variant.
调整TextStyle
以指定您想要名称的长度或缩写。请注意,在某些语言(非英语)中,如果单独使用或作为完整日期的一部分使用,月份名称会有所不同。所以每个文本样式都有一个…_STANDALONE
变体。
Specify a Locale
to determine:
指定 aLocale
来确定:
- Which human language should be used in translation.
- What cultural norms should decide issues such as abbreviation, punctuation, and capitalization.
- 翻译中应该使用哪种人类语言。
- 哪些文化规范应该决定缩写、标点符号和大小写等问题。
Example:
例子:
Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l ); // Or Locale.US, Locale.CANADA_FRENCH.
Name → Month
object
名称→Month
对象
FYI, going the other direction (parsing a name-of-month string to get a Month
enum object) is not built-in. You could write your own class to do so. Here is my quick attempt at such a class. Use at your own risk. I gave this code no serious thought nor any serious testing.
仅供参考,另一个方向(解析月份名称字符串以获取Month
枚举对象)不是内置的。你可以编写自己的类来做到这一点。这是我对此类课程的快速尝试。使用风险自负。我没有认真考虑过这段代码,也没有认真进行过任何测试。
Usage.
用法。
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." );
}
}
}
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现 java.time 类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。