.. | .. |
---|
3 | 3 | import java.util.*; |
---|
4 | 4 | import java.text.*; |
---|
5 | 5 | |
---|
6 | | -public class TimeUnit { |
---|
| 6 | +public class TimeUnit |
---|
| 7 | +{ |
---|
| 8 | + public static final TimeUnit YEAR = new TimeUnit("Years", Calendar.YEAR, 365 * 24 * 60 * 60 * 1000L, "yyyy", "yyyy"); |
---|
| 9 | + public static final TimeUnit MONTH = new TimeUnit("Months", Calendar.MONTH, 30 * 24 * 60 * 60 * 1000L, "MMM", "MMM yyyy"); |
---|
| 10 | + public static final TimeUnit WEEK = new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7 * 24 * 60 * 60 * 1000L, "d", "MMM d yyyy"); |
---|
| 11 | + public static final TimeUnit DAY = new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy"); |
---|
| 12 | + public static final TimeUnit DAY_OF_WEEK = new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy"); |
---|
| 13 | + public static final TimeUnit HOUR = new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60 * 60 * 1000L, "HH:mm", "MMM d yyyy HH:mm"); |
---|
| 14 | + public static final TimeUnit MINUTE = new TimeUnit("Minutes", Calendar.MINUTE, 60 * 1000L, ":mm", "MMM d yyyy HH:mm"); |
---|
| 15 | + public static final TimeUnit SECOND = new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy HH:mm:ss"); |
---|
| 16 | + public static final TimeUnit REALTIME = new TimeUnit("Realtime", Calendar.MILLISECOND, 8L, ":SSS", "MMM d yyyy HH:mm:ss:SSS"); |
---|
| 17 | + |
---|
| 18 | + public static final TimeUnit DECADE = multipleYears(10); |
---|
| 19 | + public static final TimeUnit CENTURY = multipleYears(100); |
---|
| 20 | + private static final double DAY_SIZE = 24 * 60 * 60 * 1000L; |
---|
| 21 | + private int quantity; |
---|
| 22 | + private long roughSize; |
---|
| 23 | + private SimpleDateFormat format, fullFormat; |
---|
| 24 | + private String name; |
---|
| 25 | + private int calendarCode; |
---|
7 | 26 | |
---|
8 | | - public static final TimeUnit YEAR=new TimeUnit("Years", Calendar.YEAR, 365*24*60*60*1000L, "yyyy", "yyyy"); |
---|
9 | | - public static final TimeUnit MONTH=new TimeUnit("Months", Calendar.MONTH, 30*24*60*60*1000L, "MMM", "MMM yyyy"); |
---|
10 | | - public static final TimeUnit WEEK=new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7*24*60*60*1000L, "d", "MMM d yyyy"); |
---|
11 | | - public static final TimeUnit DAY=new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24*60*60*1000L, "d", "MMM d yyyy"); |
---|
12 | | - public static final TimeUnit DAY_OF_WEEK=new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24*60*60*1000L, "d", "MMM d yyyy"); |
---|
13 | | - public static final TimeUnit HOUR=new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60*60*1000L, "kk:mm", "MMM d yyyy kk:mm"); |
---|
14 | | - public static final TimeUnit MINUTE=new TimeUnit("Minutes", Calendar.MINUTE, 60*1000L, ":mm", "MMM d yyyy kk:mm"); |
---|
15 | | - public static final TimeUnit SECOND=new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy kk:mm:ss"); |
---|
16 | | - public static final TimeUnit DECADE=multipleYears(10); |
---|
17 | | - public static final TimeUnit CENTURY=multipleYears(100); |
---|
18 | | - |
---|
19 | | - private static final double DAY_SIZE=24*60*60*1000L; |
---|
20 | | - |
---|
21 | | - private int quantity; |
---|
22 | | - private long roughSize; |
---|
23 | | - private SimpleDateFormat format, fullFormat; |
---|
24 | | - private String name; |
---|
25 | | - private int calendarCode; |
---|
26 | | - |
---|
27 | | - private TimeUnit() |
---|
28 | | - { |
---|
29 | | - } |
---|
30 | | - |
---|
31 | | - private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern) |
---|
32 | | - { |
---|
33 | | - this.name=name; |
---|
34 | | - this.calendarCode=calendarCode; |
---|
35 | | - this.roughSize=roughSize; |
---|
36 | | - format=new SimpleDateFormat(formatPattern); |
---|
37 | | - fullFormat=new SimpleDateFormat(fullFormatPattern); |
---|
38 | | - quantity=1; |
---|
39 | | - } |
---|
40 | | - |
---|
41 | | - public String toString() |
---|
42 | | - { |
---|
43 | | - return "[TimeUnit: "+name+"]"; |
---|
44 | | - } |
---|
| 27 | + private TimeUnit() |
---|
| 28 | + { |
---|
| 29 | + } |
---|
45 | 30 | |
---|
46 | | - public static TimeUnit multipleYears(int numYears) |
---|
47 | | - { |
---|
48 | | - TimeUnit t=new TimeUnit(); |
---|
49 | | - t.name=numYears+" Years"; |
---|
50 | | - t.calendarCode=Calendar.YEAR; |
---|
51 | | - t.roughSize=YEAR.roughSize*numYears; |
---|
52 | | - t.format=YEAR.format; |
---|
53 | | - t.fullFormat=YEAR.fullFormat; |
---|
54 | | - t.quantity=numYears; |
---|
55 | | - return t; |
---|
56 | | - } |
---|
57 | | - |
---|
58 | | - public static TimeUnit multipleWeeks(int num) |
---|
59 | | - { |
---|
60 | | - TimeUnit t=new TimeUnit(); |
---|
61 | | - t.name=num+" Weeks"; |
---|
62 | | - t.calendarCode=Calendar.WEEK_OF_YEAR; |
---|
63 | | - t.roughSize=WEEK.roughSize*num; |
---|
64 | | - t.format=WEEK.format; |
---|
65 | | - t.fullFormat=WEEK.fullFormat; |
---|
66 | | - t.quantity=num; |
---|
67 | | - return t; |
---|
68 | | - } |
---|
69 | | - |
---|
70 | | - public TimeUnit times(int quantity) |
---|
71 | | - { |
---|
72 | | - TimeUnit t=new TimeUnit(); |
---|
73 | | - t.name=quantity+" "+this.name; |
---|
74 | | - t.calendarCode=this.calendarCode; |
---|
75 | | - t.roughSize=this.roughSize*quantity; |
---|
76 | | - t.format=this.format; |
---|
77 | | - t.fullFormat=this.fullFormat; |
---|
78 | | - t.quantity=quantity; |
---|
79 | | - return t; |
---|
80 | | - |
---|
81 | | - } |
---|
| 31 | + private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern) |
---|
| 32 | + { |
---|
| 33 | + this.name = name; |
---|
| 34 | + this.calendarCode = calendarCode; |
---|
| 35 | + this.roughSize = roughSize; |
---|
| 36 | + format = new SimpleDateFormat(formatPattern); |
---|
| 37 | + fullFormat = new SimpleDateFormat(fullFormatPattern); |
---|
| 38 | + quantity = 1; |
---|
| 39 | + } |
---|
82 | 40 | |
---|
83 | | - |
---|
84 | | - public int numUnitsIn(TimeUnit u) |
---|
85 | | - { |
---|
86 | | - return (int)Math.round(u.getRoughSize()/(double)getRoughSize()); |
---|
87 | | - } |
---|
88 | | - |
---|
89 | | - public boolean isDayOrLess() |
---|
90 | | - { |
---|
91 | | - return roughSize <= 24*60*60*1000L; |
---|
92 | | - } |
---|
93 | | - |
---|
94 | | - public RoughTime roundDown(long timestamp) |
---|
95 | | - { |
---|
96 | | - return round(timestamp, false); |
---|
97 | | - } |
---|
98 | | - |
---|
99 | | - public RoughTime roundUp(long timestamp) |
---|
100 | | - { |
---|
101 | | - return round(timestamp, true); |
---|
102 | | - } |
---|
103 | | - |
---|
104 | | - private static final int[] calendarUnits={Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR}; |
---|
105 | | - public RoughTime round(long timestamp, boolean up) |
---|
106 | | - { |
---|
107 | | - Calendar c=TimeUtils.cal(timestamp); |
---|
108 | | - |
---|
109 | | - if (calendarCode==Calendar.WEEK_OF_YEAR ) |
---|
110 | | - { |
---|
111 | | - c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK)); |
---|
112 | | - } |
---|
113 | | - else |
---|
114 | | - { |
---|
115 | | - |
---|
116 | | - // set to minimum all fields of finer granularity. |
---|
117 | | - int roundingCode=calendarCode; |
---|
118 | | - if (calendarCode==Calendar.WEEK_OF_YEAR || calendarCode==Calendar.DAY_OF_WEEK) |
---|
119 | | - roundingCode=Calendar.DAY_OF_MONTH; |
---|
120 | | - for (int i=0; i<calendarUnits.length; i++) |
---|
121 | | - { |
---|
122 | | - if (calendarUnits[i]==roundingCode) |
---|
123 | | - break; |
---|
124 | | - if (i==calendarUnits.length-1) |
---|
125 | | - throw new IllegalArgumentException("Unsupported Calendar Unit: "+calendarCode); |
---|
126 | | - c.set(calendarUnits[i], c.getMinimum(calendarUnits[i])); |
---|
127 | | - } |
---|
128 | | - if (quantity>1) |
---|
129 | | - { |
---|
130 | | - c.set(calendarCode, quantity*(c.get(calendarCode)/quantity)); |
---|
131 | | - } |
---|
132 | | - } |
---|
133 | | - |
---|
134 | | - // if rounding up, then add a unit at current granularity. |
---|
135 | | - if (up) |
---|
136 | | - c.add(calendarCode, quantity); |
---|
137 | | - |
---|
138 | | - return new RoughTime(c.getTimeInMillis(), this); |
---|
139 | | - } |
---|
140 | | - |
---|
141 | | - public int get(long timestamp) |
---|
142 | | - { |
---|
143 | | - Calendar c= TimeUtils.cal(timestamp); |
---|
144 | | - int n=c.get(calendarCode); |
---|
145 | | - return quantity==1 ? n : n%quantity; |
---|
146 | | - } |
---|
147 | | - |
---|
148 | | - public void addTo(RoughTime r) |
---|
149 | | - { |
---|
150 | | - addTo(r,1); |
---|
151 | | - } |
---|
152 | | - |
---|
153 | | - public void addTo(RoughTime r, int times) |
---|
154 | | - { |
---|
155 | | - Calendar c=TimeUtils.cal(r.getTime()); |
---|
156 | | - c.add(calendarCode, quantity*times); |
---|
157 | | - r.setTime(c.getTimeInMillis()); |
---|
158 | | - } |
---|
159 | | - |
---|
160 | | - // Finding the difference between two dates, in a given unit of time, |
---|
161 | | - // is much subtler than you'd think! And annoyingly, the Calendar class does not do |
---|
162 | | - // this for you, even though it actually "knows" how to do so since it |
---|
163 | | - // can add fields. |
---|
164 | | - // |
---|
165 | | - // The most vexing problem is dealing with daylight savings time, |
---|
166 | | - // which means that one day a year has 23 hours and one day has 25 hours. |
---|
167 | | - // We also have to handle the fact that months and years aren't constant lengths. |
---|
168 | | - // |
---|
169 | | - // Rather than write all this ourselves, in this code we |
---|
170 | | - // use the Calendar class to do the heavy lifting. |
---|
171 | | - public long difference(long x, long y) |
---|
172 | | - { |
---|
173 | | - // If this is not one of the hard cases, |
---|
174 | | - // just divide the timespan by the length of time unit. |
---|
175 | | - // Note that we're not worrying about hours and daylight savings time. |
---|
176 | | - if (calendarCode!=Calendar.YEAR && calendarCode!=Calendar.MONTH && |
---|
177 | | - calendarCode!=Calendar.DAY_OF_MONTH && calendarCode!=Calendar.DAY_OF_WEEK && |
---|
178 | | - calendarCode!=Calendar.WEEK_OF_YEAR) |
---|
179 | | - { |
---|
180 | | - return (x-y)/roughSize; |
---|
181 | | - } |
---|
182 | | - |
---|
183 | | - Calendar c1=TimeUtils.cal(x), c2=TimeUtils.cal(y); |
---|
184 | | - int diff=0; |
---|
185 | | - switch (calendarCode) |
---|
186 | | - { |
---|
187 | | - case Calendar.YEAR: |
---|
188 | | - return (c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))/quantity; |
---|
189 | | - |
---|
190 | | - case Calendar.MONTH: |
---|
191 | | - diff= 12*(c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))+ |
---|
192 | | - c1.get(Calendar.MONTH)-c2.get(Calendar.MONTH); |
---|
193 | | - return diff/quantity; |
---|
194 | | - |
---|
195 | | - case Calendar.DAY_OF_MONTH: |
---|
196 | | - case Calendar.DAY_OF_WEEK: |
---|
197 | | - case Calendar.DAY_OF_YEAR: |
---|
198 | | - case Calendar.WEEK_OF_MONTH: |
---|
199 | | - case Calendar.WEEK_OF_YEAR: |
---|
200 | | - // This is ugly, but believe me, it beats the alternative methods :-) |
---|
201 | | - // We use the Calendar class's knowledge of daylight savings time. |
---|
202 | | - // and also the fact that if we calculate this naively, then we aren't going |
---|
203 | | - // to be off by more than one in either direction. |
---|
204 | | - int naive=(int)Math.round((x-y)/(double)roughSize); |
---|
205 | | - c2.add(calendarCode, naive*quantity); |
---|
206 | | - if (c1.get(calendarCode)==c2.get(calendarCode)) |
---|
207 | | - return naive/quantity; |
---|
208 | | - c2.add(calendarCode, quantity); |
---|
209 | | - if (c1.get(calendarCode)==c2.get(calendarCode)) |
---|
210 | | - return naive/quantity+1; |
---|
211 | | - return naive/quantity-1; |
---|
212 | | - } |
---|
213 | | - throw new IllegalArgumentException("Unexpected calendar code: "+calendarCode); |
---|
214 | | - } |
---|
| 41 | + public String toString() |
---|
| 42 | + { |
---|
| 43 | + return "[TimeUnit: " + name + "]"; |
---|
| 44 | + } |
---|
215 | 45 | |
---|
216 | | - public long approxNumInRange(long start, long end) |
---|
217 | | - { |
---|
218 | | - return 1+(end-start)/roughSize; |
---|
219 | | - } |
---|
220 | | - |
---|
221 | | - public long getRoughSize() { |
---|
222 | | - return roughSize; |
---|
223 | | - } |
---|
| 46 | + public static TimeUnit multipleYears(int numYears) |
---|
| 47 | + { |
---|
| 48 | + TimeUnit t = new TimeUnit(); |
---|
| 49 | + t.name = numYears + " Years"; |
---|
| 50 | + t.calendarCode = Calendar.YEAR; |
---|
| 51 | + t.roughSize = YEAR.roughSize * numYears; |
---|
| 52 | + t.format = YEAR.format; |
---|
| 53 | + t.fullFormat = YEAR.fullFormat; |
---|
| 54 | + t.quantity = numYears; |
---|
| 55 | + return t; |
---|
| 56 | + } |
---|
224 | 57 | |
---|
225 | | - public String format(Date date) |
---|
226 | | - { |
---|
227 | | - return format.format(date); |
---|
228 | | - } |
---|
| 58 | + public static TimeUnit multipleWeeks(int num) |
---|
| 59 | + { |
---|
| 60 | + TimeUnit t = new TimeUnit(); |
---|
| 61 | + t.name = num + " Weeks"; |
---|
| 62 | + t.calendarCode = Calendar.WEEK_OF_YEAR; |
---|
| 63 | + t.roughSize = WEEK.roughSize * num; |
---|
| 64 | + t.format = WEEK.format; |
---|
| 65 | + t.fullFormat = WEEK.fullFormat; |
---|
| 66 | + t.quantity = num; |
---|
| 67 | + return t; |
---|
| 68 | + } |
---|
229 | 69 | |
---|
230 | | - public String formatFull(Date date) |
---|
231 | | - { |
---|
232 | | - return fullFormat.format(date); |
---|
233 | | - } |
---|
| 70 | + public TimeUnit times(int quantity) |
---|
| 71 | + { |
---|
| 72 | + TimeUnit t = new TimeUnit(); |
---|
| 73 | + t.name = quantity + " " + this.name; |
---|
| 74 | + t.calendarCode = this.calendarCode; |
---|
| 75 | + t.roughSize = this.roughSize * quantity; |
---|
| 76 | + t.format = this.format; |
---|
| 77 | + t.fullFormat = this.fullFormat; |
---|
| 78 | + t.quantity = quantity; |
---|
| 79 | + return t; |
---|
234 | 80 | |
---|
235 | | - public String formatFull(long timestamp) |
---|
236 | | - { |
---|
237 | | - return fullFormat.format(new Date(timestamp)); |
---|
238 | | - } |
---|
| 81 | + } |
---|
239 | 82 | |
---|
240 | | - public String getName() { |
---|
241 | | - return name; |
---|
242 | | - } |
---|
| 83 | + public int numUnitsIn(TimeUnit u) |
---|
| 84 | + { |
---|
| 85 | + return (int) Math.round(u.getRoughSize() / (double) getRoughSize()); |
---|
| 86 | + } |
---|
| 87 | + |
---|
| 88 | + public boolean isDayOrLess() |
---|
| 89 | + { |
---|
| 90 | + return roughSize <= 24 * 60 * 60 * 1000L; |
---|
| 91 | + } |
---|
| 92 | + |
---|
| 93 | + public RoughTime roundDown(long timestamp) |
---|
| 94 | + { |
---|
| 95 | + return round(timestamp, false); |
---|
| 96 | + } |
---|
| 97 | + |
---|
| 98 | + public RoughTime roundUp(long timestamp) |
---|
| 99 | + { |
---|
| 100 | + return round(timestamp, true); |
---|
| 101 | + } |
---|
| 102 | + private static final int[] calendarUnits = |
---|
| 103 | + { |
---|
| 104 | + Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR |
---|
| 105 | + }; |
---|
| 106 | + |
---|
| 107 | + public RoughTime round(long timestamp, boolean up) |
---|
| 108 | + { |
---|
| 109 | + Calendar c = TimeUtils.cal(timestamp); |
---|
| 110 | + |
---|
| 111 | + if (calendarCode == Calendar.WEEK_OF_YEAR) |
---|
| 112 | + { |
---|
| 113 | + c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK)); |
---|
| 114 | + } else |
---|
| 115 | + { |
---|
| 116 | + |
---|
| 117 | + // set to minimum all fields of finer granularity. |
---|
| 118 | + int roundingCode = calendarCode; |
---|
| 119 | + if (calendarCode == Calendar.WEEK_OF_YEAR || calendarCode == Calendar.DAY_OF_WEEK) |
---|
| 120 | + { |
---|
| 121 | + roundingCode = Calendar.DAY_OF_MONTH; |
---|
| 122 | + } |
---|
| 123 | + for (int i = 0; i < calendarUnits.length; i++) |
---|
| 124 | + { |
---|
| 125 | + if (calendarUnits[i] == roundingCode) |
---|
| 126 | + { |
---|
| 127 | + break; |
---|
| 128 | + } |
---|
| 129 | + if (i == calendarUnits.length - 1) |
---|
| 130 | + { |
---|
| 131 | + throw new IllegalArgumentException("Unsupported Calendar Unit: " + calendarCode); |
---|
| 132 | + } |
---|
| 133 | + c.set(calendarUnits[i], c.getMinimum(calendarUnits[i])); |
---|
| 134 | + } |
---|
| 135 | + if (quantity > 1) |
---|
| 136 | + { |
---|
| 137 | + c.set(calendarCode, quantity * (c.get(calendarCode) / quantity)); |
---|
| 138 | + } |
---|
| 139 | + } |
---|
| 140 | + |
---|
| 141 | + // if rounding up, then add a unit at current granularity. |
---|
| 142 | + if (up) |
---|
| 143 | + { |
---|
| 144 | + c.add(calendarCode, quantity); |
---|
| 145 | + } |
---|
| 146 | + |
---|
| 147 | + return new RoughTime(c.getTimeInMillis(), this); |
---|
| 148 | + } |
---|
| 149 | + |
---|
| 150 | + public int get(long timestamp) |
---|
| 151 | + { |
---|
| 152 | + Calendar c = TimeUtils.cal(timestamp); |
---|
| 153 | + int n = c.get(calendarCode); |
---|
| 154 | + return quantity == 1 ? n : n % quantity; |
---|
| 155 | + } |
---|
| 156 | + |
---|
| 157 | + public void addTo(RoughTime r) |
---|
| 158 | + { |
---|
| 159 | + addTo(r, 1); |
---|
| 160 | + } |
---|
| 161 | + |
---|
| 162 | + public void addTo(RoughTime r, int times) |
---|
| 163 | + { |
---|
| 164 | + Calendar c = TimeUtils.cal(r.getTime()); |
---|
| 165 | + c.add(calendarCode, quantity * times); |
---|
| 166 | + r.setTime(c.getTimeInMillis()); |
---|
| 167 | + } |
---|
| 168 | + |
---|
| 169 | + // Finding the difference between two dates, in a given unit of time, |
---|
| 170 | + // is much subtler than you'd think! And annoyingly, the Calendar class does not do |
---|
| 171 | + // this for you, even though it actually "knows" how to do so since it |
---|
| 172 | + // can add fields. |
---|
| 173 | + // |
---|
| 174 | + // The most vexing problem is dealing with daylight savings time, |
---|
| 175 | + // which means that one day a year has 23 hours and one day has 25 hours. |
---|
| 176 | + // We also have to handle the fact that months and years aren't constant lengths. |
---|
| 177 | + // |
---|
| 178 | + // Rather than write all this ourselves, in this code we |
---|
| 179 | + // use the Calendar class to do the heavy lifting. |
---|
| 180 | + public long difference(long x, long y) |
---|
| 181 | + { |
---|
| 182 | + // If this is not one of the hard cases, |
---|
| 183 | + // just divide the timespan by the length of time unit. |
---|
| 184 | + // Note that we're not worrying about hours and daylight savings time. |
---|
| 185 | + if (calendarCode != Calendar.YEAR && calendarCode != Calendar.MONTH |
---|
| 186 | + && calendarCode != Calendar.DAY_OF_MONTH && calendarCode != Calendar.DAY_OF_WEEK |
---|
| 187 | + && calendarCode != Calendar.WEEK_OF_YEAR) |
---|
| 188 | + { |
---|
| 189 | + return (x - y) / roughSize; |
---|
| 190 | + } |
---|
| 191 | + |
---|
| 192 | + Calendar c1 = TimeUtils.cal(x), c2 = TimeUtils.cal(y); |
---|
| 193 | + int diff = 0; |
---|
| 194 | + switch (calendarCode) |
---|
| 195 | + { |
---|
| 196 | + case Calendar.YEAR: |
---|
| 197 | + return (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR)) / quantity; |
---|
| 198 | + |
---|
| 199 | + case Calendar.MONTH: |
---|
| 200 | + diff = 12 * (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR)) |
---|
| 201 | + + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH); |
---|
| 202 | + return diff / quantity; |
---|
| 203 | + |
---|
| 204 | + case Calendar.DAY_OF_MONTH: |
---|
| 205 | + case Calendar.DAY_OF_WEEK: |
---|
| 206 | + case Calendar.DAY_OF_YEAR: |
---|
| 207 | + case Calendar.WEEK_OF_MONTH: |
---|
| 208 | + case Calendar.WEEK_OF_YEAR: |
---|
| 209 | + // This is ugly, but believe me, it beats the alternative methods :-) |
---|
| 210 | + // We use the Calendar class's knowledge of daylight savings time. |
---|
| 211 | + // and also the fact that if we calculate this naively, then we aren't going |
---|
| 212 | + // to be off by more than one in either direction. |
---|
| 213 | + int naive = (int) Math.round((x - y) / (double) roughSize); |
---|
| 214 | + c2.add(calendarCode, naive * quantity); |
---|
| 215 | + if (c1.get(calendarCode) == c2.get(calendarCode)) |
---|
| 216 | + { |
---|
| 217 | + return naive / quantity; |
---|
| 218 | + } |
---|
| 219 | + c2.add(calendarCode, quantity); |
---|
| 220 | + if (c1.get(calendarCode) == c2.get(calendarCode)) |
---|
| 221 | + { |
---|
| 222 | + return naive / quantity + 1; |
---|
| 223 | + } |
---|
| 224 | + return naive / quantity - 1; |
---|
| 225 | + } |
---|
| 226 | + throw new IllegalArgumentException("Unexpected calendar code: " + calendarCode); |
---|
| 227 | + } |
---|
| 228 | + |
---|
| 229 | + public long approxNumInRange(long start, long end) |
---|
| 230 | + { |
---|
| 231 | + return 1 + (end - start) / roughSize; |
---|
| 232 | + } |
---|
| 233 | + |
---|
| 234 | + public long getRoughSize() |
---|
| 235 | + { |
---|
| 236 | + return roughSize; |
---|
| 237 | + } |
---|
| 238 | + |
---|
| 239 | + public String format(Date date) |
---|
| 240 | + { |
---|
| 241 | + return format.format(date); |
---|
| 242 | + } |
---|
| 243 | + |
---|
| 244 | + public String formatFull(Date date) |
---|
| 245 | + { |
---|
| 246 | + return fullFormat.format(date); |
---|
| 247 | + } |
---|
| 248 | + |
---|
| 249 | + public String formatFull(long timestamp) |
---|
| 250 | + { |
---|
| 251 | + return fullFormat.format(new Date(timestamp)); |
---|
| 252 | + } |
---|
| 253 | + |
---|
| 254 | + public String getName() |
---|
| 255 | + { |
---|
| 256 | + return name; |
---|
| 257 | + } |
---|
243 | 258 | } |
---|