10 Replies Latest reply: Sep 27, 2009 2:25 PM by 843810 RSS

    Calendar data for new locales

    843810
      We're developing an aplication on JDK 6. This application needs to support Spanish and Basque. Spanish is not a problem as "es" is a supported locale for the JDK but Basque "eu" is not supported. We've used the new SPI API for defining the Date and Currency Symbols for the eu locale, this works fine.

      Our problem arises when we use the GregorianCalendar class for the "eu" locale. When we retrieve the first day of the week the method returns 1 (sunday) but in our locale it should be 2 (monday). It seems that when the locale is not known for the JDK it returns the default value (English, I supose).

      Does anyone know how to define the CalendarData for the "eu" locale? or at least, change the default value for getFirstDayOfWeek method?

      Thanks in advance,

      Juanjo
        • 1. Re: Calendar data for new locales
          843810
          The easiest way might be to just use ICU. The CLDR data used by ICU has the correct value for first day of week: http://demo.icu-project.org/icu-bin/locexp?d_=en&_=eu_ES
          • 2. Re: Calendar data for new locales
            796365
            Java,util.Calendar has the method setFirstDayOfWeek
            • 3. Re: Calendar data for new locales
              843810
              Thanks a lot for your responses,

              The real problem for my is that i'm using a third-party library in a JSF application that renders the calendar. This component is using the calendar support of the JDK 6 that provides an incorrect first day of week for the "eu" locale. We can not modify the JSF component.
              • 4. Re: Calendar data for new locales
                800025
                You may have a look at the java.text.spi and java.util.spi packages.

                With these packages you can define your own provider classes, based, for instance, on the ICU4J classes. These classes will be used throughout your JVM, so by third party software as well.

                I remember having done this once as an experiment. I don't quite remember how to activate it, but I found my source code. Just as an example here how to make use of the com.ibm.icu.text.DateFormatSymbols

                The provider class:
                package org.pbjar.icu4j;
                
                import java.text.spi.DateFormatSymbolsProvider;
                import java.util.Locale;
                
                import org.pbjar.icu4j.wrap.DateFormatSymbolsWrapper;
                
                import com.ibm.icu.text.DateFormatSymbols;
                
                
                /**
                 * Wraps com.ibm.icu.text.DateFormatSymbols.
                 * 
                 * @author Piet Blok
                 */
                public class ICU4JDateFormatSymbolsProvider extends DateFormatSymbolsProvider {
                
                    public ICU4JDateFormatSymbolsProvider() {
                    }
                
                    @Override
                    public Locale[] getAvailableLocales() {
                        return ICU4JLocales.getAvailableLocales();
                    }
                
                    @Override
                    public java.text.DateFormatSymbols getInstance(Locale locale) {
                        return new DateFormatSymbolsWrapper(new DateFormatSymbols(locale));
                    }
                
                }
                And here the wrapper class:
                package org.pbjar.icu4j.wrap;
                
                import com.ibm.icu.text.DateFormatSymbols;
                
                /**
                 * Wrapper for com.ibm.icu.text.DateFormatSymbols.
                 * 
                 * @author Piet Blok
                 */
                public class DateFormatSymbolsWrapper extends java.text.DateFormatSymbols {
                
                    private static final long serialVersionUID = 1L;
                
                    DateFormatSymbols symbols;
                
                    public DateFormatSymbolsWrapper(DateFormatSymbols symbols) {
                        this.symbols = symbols;
                    }
                
                    @SuppressWarnings("unused")
                    private DateFormatSymbolsWrapper() {
                
                    }
                
                    @Override
                    public Object clone() {
                        return new DateFormatSymbolsWrapper((DateFormatSymbols) symbols.clone());
                    }
                
                    @Override
                    public boolean equals(Object obj) {
                        return (obj instanceof DateFormatSymbolsWrapper ? symbols
                                .equals((DateFormatSymbolsWrapper) obj) : false);
                    }
                
                    @Override
                    public String[] getAmPmStrings() {
                        return symbols.getAmPmStrings();
                    }
                
                    @Override
                    public String[] getEras() {
                        return symbols.getEras();
                    }
                
                    @Override
                    public String getLocalPatternChars() {
                        return symbols.getLocalPatternChars();
                    }
                
                    @Override
                    public String[] getMonths() {
                        return symbols.getMonths();
                    }
                
                    @Override
                    public String[] getShortMonths() {
                        return symbols.getShortMonths();
                    }
                
                    @Override
                    public String[] getShortWeekdays() {
                        return symbols.getShortWeekdays();
                    }
                
                    @Override
                    public String[] getWeekdays() {
                        return symbols.getWeekdays();
                    }
                
                    @Override
                    public String[][] getZoneStrings() {
                        return symbols.getZoneStrings();
                    }
                
                    @Override
                    public int hashCode() {
                        return symbols.hashCode();
                    }
                
                    @Override
                    public void setAmPmStrings(String[] newAmpms) {
                        symbols.setAmPmStrings(newAmpms);
                    }
                
                    @Override
                    public void setEras(String[] newEras) {
                        symbols.setEras(newEras);
                    }
                
                    @Override
                    public void setLocalPatternChars(String newLocalPatternChars) {
                        symbols.setLocalPatternChars(newLocalPatternChars);
                    }
                
                    @Override
                    public void setMonths(String[] newMonths) {
                        symbols.setMonths(newMonths);
                    }
                
                    @Override
                    public void setShortMonths(String[] newShortMonths) {
                        symbols.setShortMonths(newShortMonths);
                    }
                
                    @Override
                    public void setShortWeekdays(String[] newShortWeekdays) {
                        symbols.setShortWeekdays(newShortWeekdays);
                    }
                
                    @Override
                    public void setWeekdays(String[] newWeekdays) {
                        symbols.setWeekdays(newWeekdays);
                    }
                
                    @Override
                    public void setZoneStrings(String[][] newZoneStrings) {
                        symbols.setZoneStrings(newZoneStrings);
                    }
                
                }
                Piet
                • 5. Re: Calendar data for new locales
                  843810
                  Thanks Piet,


                  We managed to localize the names of days and moths using the SPI extensión, in our case we are using an specific extension for Basque language. The problem is that the SPI does not include information about the first day of the week, this info seems to be located at sun.util.resources.CalendarData. We try to find a way to add a new CalendarData resource for the "eu" locale.

                  Juanjo
                  • 6. Re: Calendar data for new locales
                    800025
                    Ah,

                    Create a properties file with the name: sun/util/resources/CalendarData_eu_ES.properties and have this file in your classpath, either by putting it in a jar, or, by having it in a directory that is mentioned in your classpath.

                    Two key-value pairs:
                    # manually edited resource fbundle for eu_ES (Basque)
                    firstDayOfWeek=2
                    minimalDaysInFirstWeek=4
                    Is this what you wanted to know?

                    Piet
                    • 7. Re: Calendar data for new locales
                      843810
                      Yes, we try but it does not work. We tested with a properties file and with a ListResourceBundle but the JDK is not taking this bundles.

                      The question is that I try to retrieve the Bundle in the ususal way ResourceBundle.getBundle("sun.util.resources.CalendarData",new Locale("eu","ES")) and it works. IT seems that the JDK only takes the locales supported by default.

                      Any idea?

                      Thanks,

                      Jaunjo
                      • 8. Re: Calendar data for new locales
                        800025
                        That's a pity.

                        I remember once having encountered a similar problem: I created properties files for resource bundles targeted at the Swing classes (for the Dutch language). When running as a desktop application, everything ran fine and I got Swing completely translated into Dutch. However, when deployed as a web start application (on a Dutch box ofcourse) it didn't work, and I got the default Emglish version. I never found out why.

                        Sorry,

                        Piet
                        • 9. Re: Calendar data for new locales
                          843810
                          I also have tryed creating a class un.text.resources.LocaleElements_xx_XX to test a locale of my own, and it does not work, only if i create the resource bundle via an explicit call to LocaleData.getLocaleElements it does take the parameter defined inside this class.
                          • 10. Re: Calendar data for new locales
                            843810
                            Hi,

                            Have you guys found any solution to the problem? The SPI extension api is great for adding new locale specific data but it leaks firstDayOfWeek and minimalDaysInFirstWeek functionality.

                            br
                            David