Home | History | Annotate | Download | only in impl
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2009, International Business Machines Corporation and         *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  */
      7 package com.ibm.icu.impl;
      8 
      9 import java.util.MissingResourceException;
     10 
     11 import com.ibm.icu.util.ULocale;
     12 import com.ibm.icu.util.UResourceBundle;
     13 
     14 /**
     15  * Calendar utilities.
     16  *
     17  * Date/time format service classes in com.ibm.icu.text packages
     18  * sometimes need to access calendar internal APIs.  But calendar
     19  * classes are in com.ibm.icu.util package, so the package local
     20  * cannot be used.  This class is added in com.ibm.icu.impl
     21  * package for sharing some calendar internal code for calendar
     22  * and date format.
     23  */
     24 public class CalendarUtil {
     25 
     26     private static ICUCache<String, String> CALTYPE_CACHE = new SimpleCache<String, String>();
     27 
     28     private static final String CALKEY = "calendar";
     29     private static final String DEFCAL = "gregorian";
     30 
     31     /**
     32      * Returns a calendar type for the given locale.
     33      * When the given locale has calendar keyword, the
     34      * value of calendar keyword is returned.  Otherwise,
     35      * the default calendar type for the locale is returned.
     36      * @param loc The locale
     37      * @return Calendar type string, such as "gregorian"
     38      */
     39     public static String getCalendarType(ULocale loc) {
     40         String calType = null;
     41 
     42         calType = loc.getKeywordValue(CALKEY);
     43         if (calType != null) {
     44             return calType;
     45         }
     46 
     47         String baseLoc = loc.getBaseName();
     48 
     49         // Check the cache
     50         calType = CALTYPE_CACHE.get(baseLoc);
     51         if (calType != null) {
     52             return calType;
     53         }
     54 
     55         // Canonicalize, so grandfathered variant will be transformed to keywords
     56         ULocale canonical = ULocale.createCanonical(loc.toString());
     57         calType = canonical.getKeywordValue("calendar");
     58 
     59         if (calType == null) {
     60             // When calendar keyword is not available, use the locale's
     61             // region to get the default calendar type
     62             String region = canonical.getCountry();
     63             if (region.length() == 0) {
     64                 ULocale fullLoc = ULocale.addLikelySubtags(canonical);
     65                 region = fullLoc.getCountry();
     66             }
     67 
     68             // Read supplementalData to get the default calendar type for
     69             // the locale's region
     70             try {
     71                 UResourceBundle rb = UResourceBundle.getBundleInstance(
     72                                         ICUResourceBundle.ICU_BASE_NAME,
     73                                         "supplementalData",
     74                                         ICUResourceBundle.ICU_DATA_CLASS_LOADER);
     75                 UResourceBundle calPref = rb.get("calendarPreferenceData");
     76                 UResourceBundle order = null;
     77                 try {
     78                     order = calPref.get(region);
     79                 } catch (MissingResourceException mre) {
     80                     // use "001" as fallback
     81                     order = calPref.get("001");
     82                 }
     83                 // the first calendar type is the default for the region
     84                 calType = order.getString(0);
     85             } catch (MissingResourceException mre) {
     86                 // fall through
     87             }
     88 
     89             if (calType == null) {
     90                 // Use "gregorian" as the last resort fallback.
     91                 calType = DEFCAL;
     92             }
     93         }
     94 
     95         // Cache the resolved value for the next time
     96         CALTYPE_CACHE.put(baseLoc, calType);
     97 
     98         return calType;
     99     }
    100 }
    101