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 枚举定义了十几个对象,每个月一个。
一月至十二月的月份编号为 1-12。
Month month = Month.of( 2 ); // 2 → February.
要求对象生成name of the month, automatically localized 的字符串。
调整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 对象
仅供参考,不是内置的(解析月份名称字符串以获取 Month 枚举对象)。你可以编写自己的类来这样做。这是我对此类课程的快速尝试。 使用风险自负。我没有认真考虑过这段代码,也没有进行任何认真的测试。
用法。
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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。