• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html#License
3 /*
4  *******************************************************************************
5  * Copyright (C) 2009,2016 International Business Machines Corporation and
6  * others. All Rights Reserved.
7  *******************************************************************************
8  */
9 package com.ibm.icu.impl;
10 
11 import java.util.Map;
12 import java.util.MissingResourceException;
13 import java.util.TreeMap;
14 
15 import com.ibm.icu.util.ULocale;
16 import com.ibm.icu.util.UResourceBundle;
17 
18 /**
19  * Calendar utilities.
20  *
21  * Date/time format service classes in com.ibm.icu.text packages
22  * sometimes need to access calendar internal APIs.  But calendar
23  * classes are in com.ibm.icu.util package, so the package local
24  * cannot be used.  This class is added in com.ibm.icu.impl
25  * package for sharing some calendar internal code for calendar
26  * and date format.
27  */
28 public final class CalendarUtil {
29     private static final String CALKEY = "calendar";
30     private static final String DEFCAL = "gregorian";
31 
32     /**
33      * Returns a calendar type for the given locale.
34      * When the given locale has calendar keyword, the
35      * value of calendar keyword is returned.  Otherwise,
36      * the default calendar type for the locale is returned.
37      * @param loc The locale
38      * @return Calendar type string, such as "gregorian"
39      */
getCalendarType(ULocale loc)40     public static String getCalendarType(ULocale loc) {
41         String calType = loc.getKeywordValue(CALKEY);
42         if (calType != null) {
43             return calType;
44         }
45 
46         // Canonicalize, so grandfathered variant will be transformed to keywords
47         ULocale canonical = ULocale.createCanonical(loc.toString());
48         calType = canonical.getKeywordValue(CALKEY);
49         if (calType != null) {
50             return calType;
51         }
52 
53         // When calendar keyword is not available, use the locale's
54         // region to get the default calendar type
55         String region = ULocale.getRegionForSupplementalData(canonical, true);
56         return CalendarPreferences.INSTANCE.getCalendarTypeForRegion(region);
57     }
58 
59     private static final class CalendarPreferences extends UResource.Sink {
60         private static final CalendarPreferences INSTANCE = new CalendarPreferences();
61         // A TreeMap should be good because we expect very few entries.
62         Map<String, String> prefs = new TreeMap<String, String>();
63 
CalendarPreferences()64         CalendarPreferences() {
65             try {
66                 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(
67                         ICUData.ICU_BASE_NAME, "supplementalData");
68                 rb.getAllItemsWithFallback("calendarPreferenceData", this);
69             } catch (MissingResourceException mre) {
70                 // Always use "gregorian".
71             }
72         }
73 
getCalendarTypeForRegion(String region)74         String getCalendarTypeForRegion(String region) {
75             String type = prefs.get(region);
76             return type == null ? DEFCAL : type;
77         }
78 
79         @Override
put(UResource.Key key, UResource.Value value, boolean noFallback)80         public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
81             UResource.Table calendarPreferenceData = value.getTable();
82             for (int i = 0; calendarPreferenceData.getKeyAndValue(i, key, value); ++i) {
83                 UResource.Array types = value.getArray();
84                 // The first calendar type is the default for the region.
85                 if (types.getValue(0, value)) {
86                     String type = value.getString();
87                     if (!type.equals(DEFCAL)) {
88                         prefs.put(key.toString(), type);
89                     }
90                 }
91             }
92         }
93     }
94 }
95