We have a customer in Sweden, using the software in English. So we set the Locale(en, SV)
. We did hope the Calendar class would adhere to the country settings, but it uses the language and with this locale it assumes US settings.
So I am now searching for a way to let the calendar get to know the new firstDayOfWeek
and minimumDayinFirstWeek
settings preferred by a standard way other than setting it manually and thus hardcoded.
For clarification: The 29. August 2010 is in Sweden in CW 34 (also in Germany and Great Britain) but in the US it is reported as CW 36. The different results from the fact that the 01.01.2010 is a Friday and the 29.08.2010 a Sunday.
I cannot change the language setting itself to Swedish and use the English fallback since we do not support Swedish as language, but Sun/Oracle/.. does, so the Swing UI would have a mixture of Swedish and English texts, which not acceptable.
And just adding a properties file named "sun.util.resources.CalendarData_en_SV.properties" does not work out: it does not get read! Manually as a ResourceBundle that's possible. Somehow LocaleData.getCalendarData(Locale) does its own magic in reading the resourcfiles which i cannot find out since the source of it is not available. The method is called here: java.util.Calendar.setWeekCountData(Locale)
.
I also found the java.util.spi package but it does not provide access to the firstDayOfWeek and minimumDaysInFirstWeek settings.
Perhaps I can try to intercept the calls to the resourcebundles and use the default fallback to English and only let the calls to CalendarData proceed!? But that sounds hacky.
package de.drews.i18n;
import java.util.Calendar;
import java.util.Locale;
import java.util.ResourceBundle;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// en_GB = 34
// en_US = 36
// sv_SV = 34
// en_SV = 36 --> wrong
printTest("en", "GB", 34);
printTest("en", "US", 36);
printTest("sv", "SV", 34);
printTest("en", "SV", 34);
}
private static void printTest(String language, String country, int expected) {
Locale locale = new Locale(language, country);
Calendar cal = Calendar.getInstance(locale);
cal.set(Calenda开发者_如何学Gor.YEAR, 2010);
cal.set(Calendar.MONTH, Calendar.AUGUST);
cal.set(Calendar.DATE, 29);
int actual = cal.get(Calendar.WEEK_OF_YEAR);
System.out.println(actual + "\t" + expected + "\t"
+ ((actual == expected) ? "Yeah!" : "-") + "\t" + language
+ "\t" + country);
}
}
How about using getInstance(TimeZone zone, Locale aLocale)
providing a timezone to select calendar behaviour and locale to define language?
One ugly workaround that I can offer is to reflectively obtain the cachedLocaleData
static field of the Calendar
class, and put there the following:
key = new Locale(..); // your english-swedish locale
value = new int[] {firstDayOfWeek, minimalDaysInFirstWeek};
This can be done at init-time and will work for the entire application
精彩评论