How to control the capitalization of month and day names returned by DateFormat?

余生长醉 提交于 2019-12-19 12:52:51

问题


Here is a quick test program:

    public static void main( String[] args )
{
    Date date = Calendar.getInstance().getTime();

    System.out.println("Months:");
    printDate( "MMMM", "en", date );
    printDate( "MMMM", "es", date );
    printDate( "MMMM", "fr", date );
    printDate( "MMMM", "de", date );

    System.out.println("Days:");
    printDate( "EEEE", "en", date );
    printDate( "EEEE", "es", date );
    printDate( "EEEE", "fr", date );
    printDate( "EEEE", "de", date );

}

public static void printDate( String format, String locale, Date date )
{
    System.out.println( locale + ": " + (new SimpleDateFormat( format, new Locale( locale ) )).format( date ) );
}

The output is:

Months: en: September es: septiembre fr: septembre de: September Days: en: Monday es: lunes fr: lundi de: Montag

How can I control the capitalization of the names. For some reason the Spanish and French always seem to return names that start with a lowercase letter.


回答1:


Not all languages share english capitalization rules. I guess you'd need to alter the data used by the API, but your non-english clients might not appreciate it...

about.com on french capitalization




回答2:


Capitalisation rules are different for different languages. In French, month names should not be capitalised.




回答3:


You may not want to change the capitalization -- different cultures capitalize different words (for example, in German you capitalize every noun, not just proper nouns).




回答4:


tl;dr

How can I control the capitalization of the names

You don’t. Different languages and different cultures have different rules about capitalization, punctuation, abbreviation, etc.

Month.from( LocalDate.now( ZoneId.of( "Pacific/Auckland" ) ) )    // Get current month.
     .getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH )     // Localize automatically. Specify `Locale` to determine human language and cultural norms for translation. 

février

LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )                  // Get current date as seen by people in a certain region (time zone).
    .getDayOfWeek()                                               // Get the day-of-week as a pre-defined `DayOfWeek` enum object.
    .getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH )

lundi

Localize

As others stated, you should not be forcing your own parochial (US English?) notions of capitalization. Use a decent date-time library, and let it automatically localize for you.

java.time

You are using terrible old date-time classes that are now legacy, supplanted by the java.time classes.

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "Asia/Kolkata" );
LocalDate today = LocalDate.now( z );

To work with a month, extract a Month enum object. Ditto for day-of-week, DayOfWeek.

Call getDisplayName. Pass a TextStyle for abbreviation. Pass a Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such. Note that Locale has nothing to do with time zone.

Month m = today.getMonth() ;
String mNameQuébec = m.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 
String mNameGermany = m.getDisplayName( TextStyle.FULL , Locale.GERMANY ) ; 

…and…

DayOfWeek dow = today.getDayOfWeek() ;
String dowNameQuébec = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 

String dowNameGermany = dow.getDisplayName( TextStyle.FULL , Locale.GERMANY ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.

Where to obtain the java.time classes?

  • 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 6 and 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, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project 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.




回答5:


I'm having a problem now where a sentence begins with "dimanche 07 mars", which wouldn't matter if it were not at the beginning of a sentence. I guess this cannot be changed, unless I do manual string manipulation on the first character of the string.



来源:https://stackoverflow.com/questions/66750/how-to-control-the-capitalization-of-month-and-day-names-returned-by-dateformat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!