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 StringBuilder sb = new StringBuilder(_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 StringBuilder sb=new StringBuilder(_secFormatString.length());
258 sb.append(_secFormatString0);
259 int s=(int)(seconds%60);
260 if (s<10)
261 sb.append('0');
262 sb.append(s);
263 sb.append(_secFormatString1);
264 _lastResult=sb.toString();
265
266
267 return _lastResult;
268 }
269
270
271
272
273
274
275 public void format(long inDate, StringBuilder buffer)
276 {
277 buffer.append(format(inDate));
278 }
279
280
281
282
283 public SimpleDateFormat getFormat()
284 {
285 return _minFormat;
286 }
287
288
289 public String getFormatString()
290 {
291 return _formatString;
292 }
293
294
295 public String now()
296 {
297 long now=System.currentTimeMillis();
298 int n=0xfff&(int)now;
299 _lastMs=n%1000;
300 return format(now);
301 }
302
303
304 public int lastMs()
305 {
306 return _lastMs;
307 }
308 }