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