17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 2009, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.impl; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.MissingResourceException; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.UResourceBundle; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Calendar utilities. 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Date/time format service classes in com.ibm.icu.text packages 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * sometimes need to access calendar internal APIs. But calendar 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * classes are in com.ibm.icu.util package, so the package local 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * cannot be used. This class is added in com.ibm.icu.impl 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * package for sharing some calendar internal code for calendar 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and date format. 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class CalendarUtil { 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static ICUCache<String, String> CALTYPE_CACHE = new SimpleCache<String, String>(); 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String CALKEY = "calendar"; 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String DEFCAL = "gregorian"; 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns a calendar type for the given locale. 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * When the given locale has calendar keyword, the 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * value of calendar keyword is returned. Otherwise, 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the default calendar type for the locale is returned. 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param loc The locale 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return Calendar type string, such as "gregorian" 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static String getCalendarType(ULocale loc) { 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String calType = null; 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert calType = loc.getKeywordValue(CALKEY); 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (calType != null) { 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return calType; 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String baseLoc = loc.getBaseName(); 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Check the cache 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert calType = CALTYPE_CACHE.get(baseLoc); 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (calType != null) { 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return calType; 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Canonicalize, so grandfathered variant will be transformed to keywords 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale canonical = ULocale.createCanonical(loc.toString()); 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert calType = canonical.getKeywordValue("calendar"); 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (calType == null) { 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // When calendar keyword is not available, use the locale's 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // region to get the default calendar type 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String region = canonical.getCountry(); 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (region.length() == 0) { 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale fullLoc = ULocale.addLikelySubtags(canonical); 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert region = fullLoc.getCountry(); 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Read supplementalData to get the default calendar type for 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the locale's region 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle rb = UResourceBundle.getBundleInstance( 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUResourceBundle.ICU_BASE_NAME, 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "supplementalData", 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ICUResourceBundle.ICU_DATA_CLASS_LOADER); 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle calPref = rb.get("calendarPreferenceData"); 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UResourceBundle order = null; 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert order = calPref.get(region); 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (MissingResourceException mre) { 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // use "001" as fallback 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert order = calPref.get("001"); 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the first calendar type is the default for the region 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert calType = order.getString(0); 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (MissingResourceException mre) { 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // fall through 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (calType == null) { 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Use "gregorian" as the last resort fallback. 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert calType = DEFCAL; 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Cache the resolved value for the next time 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert CALTYPE_CACHE.put(baseLoc, calType); 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return calType; 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 101