1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.util;
16
17 import java.text.DateFormatSymbols;
18 import java.text.SimpleDateFormat;
19 import java.util.Date;
20 import java.util.Locale;
21 import java.util.TimeZone;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class DateCache
43 {
44 public static String DEFAULT_FORMAT="EEE MMM dd HH:mm:ss zzz yyyy";
45 private static long __hitWindow=60*60;
46 private static long __MaxMisses=10;
47
48 private String _formatString;
49 private String _tzFormatString;
50 private SimpleDateFormat _tzFormat;
51
52 private String _minFormatString;
53 private SimpleDateFormat _minFormat;
54
55 private String _secFormatString;
56 private String _secFormatString0;
57 private String _secFormatString1;
58
59 private long _lastMinutes = -1;
60 private long _lastSeconds = -1;
61 private int _lastMs = -1;
62 private String _lastResult = null;
63
64 private Locale _locale = null;
65 private DateFormatSymbols _dfs = null;
66
67
68
69
70
71
72 public DateCache()
73 {
74 this(DEFAULT_FORMAT);
75 getFormat().setTimeZone(TimeZone.getDefault());
76 }
77
78
79
80
81
82 public DateCache(String format)
83 {
84 _formatString=format;
85 setTimeZone(TimeZone.getDefault());
86
87 }
88
89
90 public DateCache(String format,Locale l)
91 {
92 _formatString=format;
93 _locale = l;
94 setTimeZone(TimeZone.getDefault());
95 }
96
97
98 public DateCache(String format,DateFormatSymbols s)
99 {
100 _formatString=format;
101 _dfs = s;
102 setTimeZone(TimeZone.getDefault());
103 }
104
105
106
107
108
109 public void setTimeZone(TimeZone tz)
110 {
111 setTzFormatString(tz);
112 if( _locale != null )
113 {
114 _tzFormat=new SimpleDateFormat(_tzFormatString,_locale);
115 _minFormat=new SimpleDateFormat(_minFormatString,_locale);
116 }
117 else if( _dfs != null )
118 {
119 _tzFormat=new SimpleDateFormat(_tzFormatString,_dfs);
120 _minFormat=new SimpleDateFormat(_minFormatString,_dfs);
121 }
122 else
123 {
124 _tzFormat=new SimpleDateFormat(_tzFormatString);
125 _minFormat=new SimpleDateFormat(_minFormatString);
126 }
127 _tzFormat.setTimeZone(tz);
128 _minFormat.setTimeZone(tz);
129 _lastSeconds=-1;
130 _lastMinutes=-1;
131 }
132
133
134 public TimeZone getTimeZone()
135 {
136 return _tzFormat.getTimeZone();
137 }
138
139
140
141
142
143
144 public void setTimeZoneID(String timeZoneId)
145 {
146 setTimeZone(TimeZone.getTimeZone(timeZoneId));
147 }
148
149
150 private void setTzFormatString(final TimeZone tz )
151 {
152 int zIndex = _formatString.indexOf( "ZZZ" );
153 if( zIndex >= 0 )
154 {
155 String ss1 = _formatString.substring( 0, zIndex );
156 String ss2 = _formatString.substring( zIndex+3 );
157 int tzOffset = tz.getRawOffset();
158
159 StringBuffer sb = new StringBuffer(_formatString.length()+10);
160 sb.append(ss1);
161 sb.append("'");
162 if( tzOffset >= 0 )
163 sb.append( '+' );
164 else
165 {
166 tzOffset = -tzOffset;
167 sb.append( '-' );
168 }
169
170 int raw = tzOffset / (1000*60);
171 int hr = raw / 60;
172 int min = raw % 60;
173
174 if( hr < 10 )
175 sb.append( '0' );
176 sb.append( hr );
177 if( min < 10 )
178 sb.append( '0' );
179 sb.append( min );
180 sb.append( '\'' );
181
182 sb.append(ss2);
183 _tzFormatString=sb.toString();
184 }
185 else
186 _tzFormatString=_formatString;
187 setMinFormatString();
188 }
189
190
191
192 private void setMinFormatString()
193 {
194 int i = _tzFormatString.indexOf("ss.SSS");
195 int l = 6;
196 if (i>=0)
197 throw new IllegalStateException("ms not supported");
198 i = _tzFormatString.indexOf("ss");
199 l=2;
200
201
202 String ss1=_tzFormatString.substring(0,i);
203 String ss2=_tzFormatString.substring(i+l);
204 _minFormatString =ss1+"'ss'"+ss2;
205 }
206
207
208
209
210
211
212 public synchronized String format(Date inDate)
213 {
214 return format(inDate.getTime());
215 }
216
217
218
219
220
221
222 public synchronized String format(long inDate)
223 {
224 long seconds = inDate / 1000;
225
226
227 if (seconds<_lastSeconds ||
228 _lastSeconds>0 && seconds>_lastSeconds+__hitWindow)
229 {
230
231 Date d = new Date(inDate);
232 return _tzFormat.format(d);
233
234 }
235
236
237
238 if (_lastSeconds==seconds )
239 return _lastResult;
240
241 Date d = new Date(inDate);
242
243
244 long minutes = seconds/60;
245 if (_lastMinutes != minutes)
246 {
247 _lastMinutes = minutes;
248 _secFormatString=_minFormat.format(d);
249
250 int i=_secFormatString.indexOf("ss");
251 int l=2;
252 _secFormatString0=_secFormatString.substring(0,i);
253 _secFormatString1=_secFormatString.substring(i+l);
254 }
255
256
257 _lastSeconds = seconds;
258 StringBuffer sb=new StringBuffer(_secFormatString.length());
259 synchronized(sb)
260 {
261 sb.append(_secFormatString0);
262 int s=(int)(seconds%60);
263 if (s<10)
264 sb.append('0');
265 sb.append(s);
266 sb.append(_secFormatString1);
267 _lastResult=sb.toString();
268 }
269
270 return _lastResult;
271 }
272
273
274
275
276
277
278 public void format(long inDate, StringBuffer buffer)
279 {
280 buffer.append(format(inDate));
281 }
282
283
284
285
286 public SimpleDateFormat getFormat()
287 {
288 return _minFormat;
289 }
290
291
292 public String getFormatString()
293 {
294 return _formatString;
295 }
296
297
298 public String now()
299 {
300 long now=System.currentTimeMillis();
301 int n=0xfff&(int)now;
302 _lastMs=n%1000;
303 return format(now);
304 }
305
306
307 public int lastMs()
308 {
309 return _lastMs;
310 }
311 }