How to capitalize the first letter of the three letters month name date in Java 8
Asked Answered
E

4

5

I have the following string that represents a date like this "20190123" and I want to to convert it into this format "25 Dic 2019" the month name should be in Spanish and the first letter should be in uppercase so far I have this

    String input = "12252013";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMddyyyy" );
    LocalDate localDate = LocalDate.parse( input , formatter );
    Locale spanishLocale=new Locale("es", "ES");
    String dateInSpanish=localDate.format(DateTimeFormatter.ofPattern("dd MMM, yyyy",spanishLocale));
    System.out.println("'2016-01-01' in Spanish: "+dateInSpanish);

this prints "25 dic, 2013" I want it to be like this "25 Dic 2019"

Endarch answered 18/3, 2019 at 2:25 Comment(2)
The reason that the month is not capitalized in this output, is that the names of the months are not normally capitalized in Spanish: spanishdict.com/guide/capitalization-in-spanishExpository
Great link, @ScottW! Allow me to quote from it: “Spanish does not capitalize: days of the week, months, languages, nationalities, religions, the first word in geographical names”.Ovenbird
H
3

DateTimeFormatter uses the month names and capitalization according to the locale rules.

In English its mandatory to have the first letter of month Capitalized which is not the case in spanish. For spanish it is mandatory to have it as small letters as per RAE

You will have to use the class DateFormatSymbols to override the month names like below OR just have to convert the final string's in your case dateInspanish first letter after the first space to caps by writing some code.

Solution only applicable to Java7 or lower. For Java 8 and higher check out @Ole V.V. 's Answer

        String input = "12252013";
        Locale spanishLocale=new Locale("es", "ES");

        DateFormatSymbols sym = DateFormatSymbols.getInstance(spanishLocale);
        sym.setMonths(new String[]{"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre" });
        sym.setShortMonths(new String[]{"Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic" });

        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, spanishLocale);
        SimpleDateFormat sdf = (SimpleDateFormat) df;
        sdf.setDateFormatSymbols(sym);

        Date inputDate = new SimpleDateFormat("MMddyyyy").parse(input);

        String dateInSpanish = sdf.format(inputDate);
        System.out.println(dateInSpanish);
Hardened answered 18/3, 2019 at 4:43 Comment(2)
Please don’t teach the young ones to use the long outdated and notoriously troublesome SimpleDateFormat class. At least not as the first option. And not without any reservation. Today we have so much better in java.time, the modern Java date and time API and its DateTimeFormatter. Which is even what the question asks about. So I consider deviating from that bad advice.Ovenbird
@OleV.V. My intention was not to promote simpleDateFormat. Thanks for the advice will keep that in mind and will try to update my answer soon.Hardened
O
2

This is the discouraged answer! I suppose that you speak and write Spanish better than I do, but my understanding is that Spanish — like possibly most of the languages of the world — uses a small first letter in month names. Of course you write “Diciembre es un mes frío” (December is a cold month; from Google Translate), but in the middle of “25 dic, 2013” you need a small d.

In any case, Java can of course produce incorrect output if you instruct it to produce incorrect output. So if your users insist:

    Locale spanishLocale = new Locale("es", "ES");
    Map<Long, String> monthAbbreviations = Stream.of(Month.values())
            .collect(Collectors.toMap(m -> Long.valueOf(m.getValue()), 
                    m -> {
                        String abbrev = m.getDisplayName(TextStyle.SHORT, spanishLocale);
                        // Capitalize first letter against Spanish usage
                        return abbrev.substring(0, 1).toUpperCase(spanishLocale)
                                + abbrev.substring(1);
                    }));
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("dd ")
            .appendText(ChronoField.MONTH_OF_YEAR, monthAbbreviations)
            .appendPattern(", yyyy")
            .toFormatter(spanishLocale);

    LocalDate localDate = LocalDate.of(2013, Month.DECEMBER, 25);
    String dateInSpanish=localDate.format(formatter);
    System.out.println("'2013-12-25' in Spanish with non-current capitalization: " + dateInSpanish);

'2013-12-25' in Spanish with non-current capitalization: 25 Dic., 2013

If you don’t want the dot signifying the abbreviation, modify the code to remove that too.

Link: Months of the year in many different languages

Ovenbird answered 19/3, 2019 at 8:16 Comment(0)
O
1

Feature, not a bug

The proper localization for Spanish in Spain uses lowercase for month name.

Your desire for the first letter to be uppercase is incorrect. If you insist on that result, you will need to hard-code a solution rather than rely on the automatic localization feature.

CLDR

FYI, the default source of localization rules for most implementations of modern Java is the Common Locale Data Repository (CLDR) published by the Unicode Consortium. This database of rules is rich with details for nearly all cultures and a surprising number of sub-cultures.

If you believe your expected case of localization is correct, then I suggest exploring those finer sub-culture rules.

Otiliaotina answered 18/3, 2019 at 3:51 Comment(0)
O
0
dateString = "14/feb/2020";
        dateString = UtilsDate.capitalizeDate(dateString);

...

    public static String capitalizeDate(String dateString) {

    StringBuilder dateStringBuilder = new StringBuilder(dateString.toLowerCase());

    for (int i = 0; i < dateStringBuilder.length(); i++) {

        char c = dateStringBuilder.charAt(i);

        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {

            dateStringBuilder.setCharAt(i, Character.toUpperCase(dateStringBuilder.charAt(i)));

            break;
        }
    }

    return dateStringBuilder.toString();
}
Obturate answered 14/2, 2020 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.