1458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux/*
2458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * Copyright (C) 2016 The Android Open Source Project
3458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux *
4458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * Licensed under the Apache License, Version 2.0 (the "License");
5458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * you may not use this file except in compliance with the License.
6458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * You may obtain a copy of the License at
7458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux *
8458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux *      http://www.apache.org/licenses/LICENSE-2.0
9458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux *
10458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * Unless required by applicable law or agreed to in writing, software
11458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * distributed under the License is distributed on an "AS IS" BASIS,
12458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * See the License for the specific language governing permissions and
14458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * limitations under the License.
15458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux */
16458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
17458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuxpackage com.android.deskclock.uidata;
18458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
19458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport android.content.BroadcastReceiver;
20458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport android.content.Context;
21458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport android.content.Intent;
22458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport android.content.IntentFilter;
23ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieuximport android.util.ArrayMap;
24458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport android.util.SparseArray;
25458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
26458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport java.text.SimpleDateFormat;
27458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport java.util.Calendar;
28458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport java.util.GregorianCalendar;
29458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport java.util.Locale;
30ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieuximport java.util.Map;
31458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
32458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuximport static java.util.Calendar.JULY;
33458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
34458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux/**
35458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux * All formatted strings that are cached for performance are accessed via this model.
36458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux */
37458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieuxfinal class FormattedStringModel {
38458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
39458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /** Clears data structures containing data that is locale-sensitive. */
40458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    @SuppressWarnings("FieldCanBeLocal")
41458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    private final BroadcastReceiver mLocaleChangedReceiver = new LocaleChangedReceiver();
42458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
43458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
44458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * Caches formatted numbers in the current locale padded with zeroes to requested lengths.
45458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * The first level of the cache maps length to the second level of the cache.
46458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * The second level of the cache maps an integer to a formatted String in the current locale.
47458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
48458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    private final SparseArray<SparseArray<String>> mNumberFormatCache = new SparseArray<>(3);
49458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
50458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /** Single-character version of weekday names; e.g.: 'S', 'M', 'T', 'W', 'T', 'F', 'S' */
51ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux    private Map<Integer, String> mShortWeekdayNames;
52458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
53458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /** Full weekday names; e.g.: 'Sunday', 'Monday', 'Tuesday', etc. */
54ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux    private Map<Integer, String> mLongWeekdayNames;
55458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
56458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    FormattedStringModel(Context context) {
57458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        // Clear caches affected by locale when locale changes.
58458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        final IntentFilter localeBroadcastFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
59458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        context.registerReceiver(mLocaleChangedReceiver, localeBroadcastFilter);
60458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
61458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
62458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
63458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * This method is intended to be used when formatting numbers occurs in a hotspot such as the
64458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * update loop of a timer or stopwatch. It returns cached results when possible in order to
65458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * provide speed and limit garbage to be collected by the virtual machine.
66458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *
67458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param value a positive integer to format as a String
68458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @return the {@code value} formatted as a String in the current locale
69458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @throws IllegalArgumentException if {@code value} is negative
70458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
71458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    String getFormattedNumber(int value) {
72458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        final int length = value == 0 ? 1 : ((int) Math.log10(value) + 1);
73458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        return getFormattedNumber(false, value, length);
74458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
75458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
76458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
77458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * This method is intended to be used when formatting numbers occurs in a hotspot such as the
78458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * update loop of a timer or stopwatch. It returns cached results when possible in order to
79458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * provide speed and limit garbage to be collected by the virtual machine.
80458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *
81458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param value a positive integer to format as a String
82458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param length the length of the String; zeroes are padded to match this length
83458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @return the {@code value} formatted as a String in the current locale and padded to the
84458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *      requested {@code length}
85458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @throws IllegalArgumentException if {@code value} is negative
86458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
87458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    String getFormattedNumber(int value, int length) {
88458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        return getFormattedNumber(false, value, length);
89458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
90458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
91458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
92458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * This method is intended to be used when formatting numbers occurs in a hotspot such as the
93458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * update loop of a timer or stopwatch. It returns cached results when possible in order to
94458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * provide speed and limit garbage to be collected by the virtual machine.
95458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *
96458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param negative force a minus sign (-) onto the display, even if {@code value} is {@code 0}
97458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param value a positive integer to format as a String
98458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @param length the length of the String; zeroes are padded to match this length. If
99458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *      {@code negative} is {@code true} the return value will contain a minus sign and a total
100458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *      length of {@code length + 1}.
101458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @return the {@code value} formatted as a String in the current locale and padded to the
102458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     *      requested {@code length}
103458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @throws IllegalArgumentException if {@code value} is negative
104458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
105458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    String getFormattedNumber(boolean negative, int value, int length) {
106458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        if (value < 0) {
107458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            throw new IllegalArgumentException("value may not be negative: " + value);
108458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
109458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
110458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        // Look up the value cache using the length; -ve and +ve values are cached separately.
111458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        final int lengthCacheKey = negative ? -length : length;
112458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        SparseArray<String> valueCache = mNumberFormatCache.get(lengthCacheKey);
113458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        if (valueCache == null) {
114458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            valueCache = new SparseArray<>((int) Math.pow(10, length));
115458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            mNumberFormatCache.put(lengthCacheKey, valueCache);
116458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
117458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
118458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        // Look up the cached formatted value using the value.
119458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        String formatted = valueCache.get(value);
120458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        if (formatted == null) {
121458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            final String sign = negative ? "−" : "";
122458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            formatted = String.format(Locale.getDefault(), sign + "%0" + length + "d", value);
123458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            valueCache.put(value, formatted);
124458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
125458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
126458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        return formatted;
127458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
128458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
129458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
130ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     * @param calendarDay any of the following values
131ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <ul>
132ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#SUNDAY}</li>
133ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#MONDAY}</li>
134ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#TUESDAY}</li>
135ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#WEDNESDAY}</li>
136ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#THURSDAY}</li>
137ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#FRIDAY}</li>
138ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#SATURDAY}</li>
139ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     </ul>
140ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     * @return single-character weekday name; e.g.: 'S', 'M', 'T', 'W', 'T', 'F', 'S'
141458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
142ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux    String getShortWeekday(int calendarDay) {
143458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        if (mShortWeekdayNames == null) {
144ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux            mShortWeekdayNames = new ArrayMap<>(7);
145458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
146458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            final SimpleDateFormat format = new SimpleDateFormat("ccccc", Locale.getDefault());
147ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux            for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) {
148ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                final Calendar calendar = new GregorianCalendar(2014, JULY, 20 + i - 1);
149ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                final String weekday = format.format(calendar.getTime());
150ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                mShortWeekdayNames.put(i, weekday);
151458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            }
152458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
153458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
154ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux        return mShortWeekdayNames.get(calendarDay);
155458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
156458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
157458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
158ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     * @param calendarDay any of the following values
159ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <ul>
160ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#SUNDAY}</li>
161ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#MONDAY}</li>
162ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#TUESDAY}</li>
163ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#WEDNESDAY}</li>
164ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#THURSDAY}</li>
165ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#FRIDAY}</li>
166ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     <li>{@link Calendar#SATURDAY}</li>
167ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux     *                     </ul>
168458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * @return full weekday name; e.g.: 'Sunday', 'Monday', 'Tuesday', etc.
169458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
170ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux    String getLongWeekday(int calendarDay) {
171458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        if (mLongWeekdayNames == null) {
172ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux            mLongWeekdayNames = new ArrayMap<>(7);
173458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
174ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux            final Calendar calendar = new GregorianCalendar(2014, JULY, 20);
175458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            final SimpleDateFormat format = new SimpleDateFormat("EEEE", Locale.getDefault());
176ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux            for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) {
177ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                final String weekday = format.format(calendar.getTime());
178ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                mLongWeekdayNames.put(i, weekday);
179ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux                calendar.add(Calendar.DAY_OF_YEAR, 1);
180458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            }
181458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
182458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
183ff17acface9b98eba868fff0e2d70ddc85c5e4dbJames Lemieux        return mLongWeekdayNames.get(calendarDay);
184458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
185458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux
186458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    /**
187458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     * Cached information that is locale-sensitive must be cleared in response to locale changes.
188458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux     */
189458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    private final class LocaleChangedReceiver extends BroadcastReceiver {
190458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        @Override
191458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        public void onReceive(Context context, Intent intent) {
192458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            mNumberFormatCache.clear();
193458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            mShortWeekdayNames = null;
194458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux            mLongWeekdayNames = null;
195458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux        }
196458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux    }
197458aa8b4ebb8b7c6fdc0680a1b687ea21a61bf35James Lemieux}