1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.webkit;
18 
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.util.PluralsMessageFormatter;
22 
23 import com.android.icu.text.DateSorterBridge;
24 
25 import java.util.Calendar;
26 import java.util.HashMap;
27 import java.util.Locale;
28 import java.util.Map;
29 
30 /**
31  * Sorts dates into the following groups:
32  *   Today
33  *   Yesterday
34  *   seven days ago
35  *   one month ago
36  *   older than a month ago
37  */
38 
39 public class DateSorter {
40 
41     private static final String LOGTAG = "webkit";
42 
43     /** must be >= 3 */
44     public static final int DAY_COUNT = 5;
45 
46     private long [] mBins = new long[DAY_COUNT-1];
47     private String [] mLabels = new String[DAY_COUNT];
48 
49     private static final int NUM_DAYS_AGO = 7;
50 
51     /**
52      * @param context Application context
53      */
DateSorter(Context context)54     public DateSorter(Context context) {
55         Resources resources = context.getResources();
56 
57         Calendar c = Calendar.getInstance();
58         beginningOfDay(c);
59 
60         // Create the bins
61         mBins[0] = c.getTimeInMillis(); // Today
62         c.add(Calendar.DAY_OF_YEAR, -1);
63         mBins[1] = c.getTimeInMillis();  // Yesterday
64         c.add(Calendar.DAY_OF_YEAR, -(NUM_DAYS_AGO - 1));
65         mBins[2] = c.getTimeInMillis();  // Five days ago
66         c.add(Calendar.DAY_OF_YEAR, NUM_DAYS_AGO); // move back to today
67         c.add(Calendar.MONTH, -1);
68         mBins[3] = c.getTimeInMillis();  // One month ago
69 
70         // build labels
71         Locale locale = resources.getConfiguration().locale;
72         if (locale == null) {
73             locale = Locale.getDefault();
74         }
75         DateSorterBridge dateSorterBridge = DateSorterBridge.createInstance(locale);
76         mLabels[0] = dateSorterBridge.getToday();
77         mLabels[1] = dateSorterBridge.getYesterday();
78 
79         Map<String, Object> arguments = new HashMap<>();
80         arguments.put("count", NUM_DAYS_AGO);
81         mLabels[2] = PluralsMessageFormatter.format(
82                 resources,
83                 arguments,
84                 com.android.internal.R.string.last_num_days);
85 
86         mLabels[3] = context.getString(com.android.internal.R.string.last_month);
87         mLabels[4] = context.getString(com.android.internal.R.string.older);
88     }
89 
90     /**
91      * @param time time since the Epoch in milliseconds, such as that
92      * returned by Calendar.getTimeInMillis()
93      * @return an index from 0 to (DAY_COUNT - 1) that identifies which
94      * date bin this date belongs to
95      */
getIndex(long time)96     public int getIndex(long time) {
97         int lastDay = DAY_COUNT - 1;
98         for (int i = 0; i < lastDay; i++) {
99             if (time > mBins[i]) return i;
100         }
101         return lastDay;
102     }
103 
104     /**
105      * @param index date bin index as returned by getIndex()
106      * @return string label suitable for display to user
107      */
getLabel(int index)108     public String getLabel(int index) {
109         if (index < 0 || index >= DAY_COUNT) return "";
110         return mLabels[index];
111     }
112 
113 
114     /**
115      * @param index date bin index as returned by getIndex()
116      * @return date boundary at given index
117      */
getBoundary(int index)118     public long getBoundary(int index) {
119         int lastDay = DAY_COUNT - 1;
120         // Error case
121         if (index < 0 || index > lastDay) index = 0;
122         // Since this provides a lower boundary on dates that will be included
123         // in the given bin, provide the smallest value
124         if (index == lastDay) return Long.MIN_VALUE;
125         return mBins[index];
126     }
127 
128     /**
129      * Calcuate 12:00am by zeroing out hour, minute, second, millisecond
130      */
beginningOfDay(Calendar c)131     private void beginningOfDay(Calendar c) {
132         c.set(Calendar.HOUR_OF_DAY, 0);
133         c.set(Calendar.MINUTE, 0);
134         c.set(Calendar.SECOND, 0);
135         c.set(Calendar.MILLISECOND, 0);
136     }
137 }
138