JDK-8047872 : Need more rigorous way to get locale-specific Date and Time formats
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 7u55
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86
  • Submitted: 2014-06-21
  • Updated: 2022-12-22
  • Resolved: 2022-12-22
Related Reports
Duplicate :  
Description
A DESCRIPTION OF THE REQUEST :
I need a way to get a Time format pattern that reliably includes seconds, and another that includes milliseconds, for any locale.  Right now, I can specify the FULL for the time format, and for some Locales I get seconds, but for others, I don't.  And there is no way to ask for a formatter that includes milliseconds. 

JUSTIFICATION :
My business requirements call for a two ways to express a Time value, formatted for the default Locale. I need one way that includes seconds, and another that includes milliseconds. But there is no way to get this information from the getDateTimeInstance() or getTimeInstance() methods. This means I need to add special code to insert a seconds field into the pattern if it's missing. If I need milliseconds, I need to do the same for that field, too, but I also need to figure out what the decimal character is for the Locale. This code gets hairy, and it defeats the purpose of letting me ask for a formatter for a specific Locale.

Locales are very useful for proving the proper syntax, but I don't want them deciding which fields to include, because that's determined by my business requirements, not by the local custom. 



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like a way to ask for a formatter that lets me say if I need seconds, or milliseconds. For example, a third parameter could be added where a new constant specifies the precision:

DateFormat fmt = DateFormat.getTimeInstance(DateFormat.FULL, locale, PRECISION_SECONDS);
DateFormat fmt2 = DateFormat.getTimeInstance(DateFormat.FULL, locale, PRECISION_MILLISECONDS);

Alternatively, new methods could serve to address this:

DateFormat fmt = DateFormat.getTimeInstanceWithSeconds(locale);
DateFormat fmt2 = DateFormat.getTimeInstanceWithMillis(locale);

These methods would return a formatter that inlcudes fields of the specified precision, regardless of the specified style.

ACTUAL -
Calling getTimeInstance(DateFormat.FULL, locale) will usually return a format with seconds, but some locales don't. (sv_SE, it_CH, de_*, pt_PT, for example.) None of the methods return a time that includes milliseconds. 

---------- BEGIN SOURCE ----------
/*
 * Copyright (C) 2014, Cast & Crew (R) Software, LLC
 * All rights reserved.  Unauthorized disclosure or distribution is prohibited.
 */
package com.fun;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * DateFormatTest
 * <p/>
 * Lines beginning with a * do not include a field for seconds.
 *
 * @author <a href="mailto:miguel.munoz@castandcrew.com">Miguel Mu\u00f1oz</a>
 */
public final class DateFormatTest {
    private DateFormatTest() { }


    // ------------------------------------------------------------------------------------------------- //
    // Only used by internal main() method.

    public static void main(final String[] args) throws ParseException {
        Locale[] allLocales = Locale.getAvailableLocales();
        java.util.Comparator<Locale> comparator = new java.util.Comparator<Locale>() {
            @Override
            public int compare(final Locale o1, final Locale o2) {
                int returnValue = o1.getLanguage().compareTo(o2.getLanguage());
                if (returnValue == 0) {
                    returnValue = o1.getCountry().compareTo(o2.getCountry());
                    if (returnValue == 0) {
                        returnValue = o1.getVariant().compareTo(o2.getVariant());
                    }
                }
                return returnValue;
            }
        };
        java.util.Arrays.sort(allLocales, comparator);
        for (Locale locale : allLocales) {
            SimpleDateFormat format = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.FULL, locale);
            String today = format.format(new Date());
            String pattern = format.toPattern();
            char okay = pattern.contains("ss") ? ' ' : '*';
            SimpleDateFormat dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.FULL, locale);
            String dateTimePattern = String.format("[%s]", dateTimeFormat.toPattern());
            System.out.printf("%c %-32s for %-9s   %-38s %-49s -> %-10s %-22s%n", okay, today, locale, pattern,
                    dateTimePattern, locale.getDisplayLanguage(), locale.getDisplayCountry());
        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
It's a lot of work to add the specified fields according to local conventions.


Comments
Provided a more flexible date/time format with JDK-8176706
22-12-2022