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
Beaucoup plus facile à faire maintenant dans les classes java.time qui remplacent ces anciennes classes de date-heure héritées.
L' Month
énumération définit une douzaine d'objets, un pour chaque mois.
Les mois sont numérotés de 1 à 12 pour janvier-décembre.
Month month = Month.of( 2 ); // 2 → February.
Demandez à l'objet de générer une chaîne du nom du mois, automatiquement localisée .
Ajustez le TextStyle
pour spécifier la longueur ou l'abréviation du nom. Notez que dans certaines langues (pas l'anglais), le nom du mois varie s'il est utilisé seul ou dans le cadre d'une date complète. Ainsi, chaque style de texte a une …_STANDALONE
variante.
Spécifiez un Locale
pour déterminer:
- Quelle langue humaine doit être utilisée dans la traduction.
- Quelles normes culturelles devraient décider des questions telles que l'abréviation, la ponctuation et la capitalisation.
Exemple:
Locale l = new Locale( "es" , "MX" );
String output = Month.FEBRUARY.getDisplayName( TextStyle.SHORT_STANDALONE , l ); // Or Locale.US, Locale.CANADA_FRENCH.
Nom → Month
objet
Pour info, aller dans l'autre sens (analyser une chaîne de nom du mois pour obtenir un Month
objet enum) n'est pas intégré. Vous pouvez écrire votre propre classe pour le faire. Voici ma tentative rapide pour une telle classe. Utilisez à vos risques et périls . Je n'ai donné à ce code aucune pensée sérieuse ni aucun test sérieux.
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." );
}
}
}
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date
, Calendar
, et SimpleDateFormat
.
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*
classes.
Où obtenir les classes java.time?
- Java SE 8 , Java SE 9 et versions ultérieures
- Intégré.
- Partie de l'API Java standard avec une implémentation groupée.
- Java 9 ajoute quelques fonctionnalités et corrections mineures.
- Java SE 6 et Java SE 7
- Une grande partie de la fonctionnalité java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
- Android
- Versions ultérieures des implémentations de bundle Android des classes java.time.
- Pour les versions antérieures d'Android (<26), le versionsprojetThreeTenABPadapteThreeTen-Backport(mentionné ci-dessus). Voir Comment utiliser ThreeTenABP… .
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval
,YearWeek
, YearQuarter
et plus .