KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > util > DateCache


1 // ========================================================================
2
// $Id: DateCache.java,v 1.15 2004/05/09 20:32:49 gregwilkins Exp $
3
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.util;
17
18 import java.text.DateFormatSymbols JavaDoc;
19 import java.text.SimpleDateFormat JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.util.Locale JavaDoc;
22 import java.util.TimeZone JavaDoc;
23
24 /* ------------------------------------------------------------ */
25 /** Date Format Cache.
26  * Computes String representations of Dates and caches
27  * the results so that subsequent requests within the same minute
28  * will be fast.
29  *
30  * Only format strings that contain either "ss" or "ss.SSS" are
31  * handled.
32  *
33  * The timezone of the date may be included as an ID with the "zzz"
34  * format string or as an offset with the "ZZZ" format string.
35  *
36  * If consecutive calls are frequently very different, then this
37  * may be a little slower than a normal DateFormat.
38  *
39  * @version $Id: DateCache.java,v 1.15 2004/05/09 20:32:49 gregwilkins Exp $
40  * @author Kent Johnson <KJohnson@transparent.com>
41  * @author Greg Wilkins (gregw)
42  */

43
44 public class DateCache
45 {
46     private static long __hitWindow=60*60;
47     private static long __MaxMisses=10;
48     
49     private String JavaDoc _formatString;
50     private String JavaDoc _tzFormatString;
51     private SimpleDateFormat JavaDoc _tzFormat;
52     
53     private String JavaDoc _minFormatString;
54     private SimpleDateFormat JavaDoc _minFormat;
55
56     private String JavaDoc _secFormatString;
57     private String JavaDoc _secFormatString0;
58     private String JavaDoc _secFormatString1;
59
60     private boolean _millis=false;
61     private long _misses = 0;
62     private long _lastMinutes = -1;
63     private long _lastSeconds = -1;
64     private String JavaDoc _lastResult = null;
65
66     private Locale JavaDoc _locale = null;
67     private DateFormatSymbols JavaDoc _dfs = null;
68
69     /* ------------------------------------------------------------ */
70     /** Constructor.
71      * Make a DateCache that will use a default format. The default format
72      * generates the same results as Date.toString().
73      */

74     public DateCache()
75     {
76         this("EEE MMM dd HH:mm:ss zzz yyyy");
77         getFormat().setTimeZone(TimeZone.getDefault());
78     }
79     
80     /* ------------------------------------------------------------ */
81     /** Constructor.
82      * Make a DateCache that will use the given format
83      */

84     public DateCache(String JavaDoc format)
85     {
86         _formatString=format;
87         setTimeZone(TimeZone.getDefault());
88         
89     }
90     
91     /* ------------------------------------------------------------ */
92     public DateCache(String JavaDoc format,Locale JavaDoc l)
93     {
94         _formatString=format;
95         _locale = l;
96         setTimeZone(TimeZone.getDefault());
97     }
98     
99     /* ------------------------------------------------------------ */
100     public DateCache(String JavaDoc format,DateFormatSymbols JavaDoc s)
101     {
102         _formatString=format;
103         _dfs = s;
104         setTimeZone(TimeZone.getDefault());
105     }
106
107     /* ------------------------------------------------------------ */
108     /** Set the timezone.
109      * @param tz TimeZone
110      */

111     public void setTimeZone(TimeZone JavaDoc tz)
112     {
113         setTzFormatString(tz);
114         if( _locale != null )
115         {
116             _tzFormat=new SimpleDateFormat JavaDoc(_tzFormatString,_locale);
117             _minFormat=new SimpleDateFormat JavaDoc(_minFormatString,_locale);
118         }
119         else if( _dfs != null )
120         {
121             _tzFormat=new SimpleDateFormat JavaDoc(_tzFormatString,_dfs);
122             _minFormat=new SimpleDateFormat JavaDoc(_minFormatString,_dfs);
123         }
124         else
125         {
126             _tzFormat=new SimpleDateFormat JavaDoc(_tzFormatString);
127             _minFormat=new SimpleDateFormat JavaDoc(_minFormatString);
128         }
129         _tzFormat.setTimeZone(tz);
130         _minFormat.setTimeZone(tz);
131         _lastSeconds=-1;
132         _lastMinutes=-1;
133     }
134
135     /* ------------------------------------------------------------ */
136     public TimeZone JavaDoc getTimeZone()
137     {
138         return _tzFormat.getTimeZone();
139     }
140     
141     /* ------------------------------------------------------------ */
142     /** Set the timezone.
143      * @param timeZoneId TimeZoneId the ID of the zone as used by
144      * TimeZone.getTimeZone(id)
145      */

146     public void setTimeZoneID(String JavaDoc timeZoneId)
147     {
148         setTimeZone(TimeZone.getTimeZone(timeZoneId));
149     }
150     
151     /* ------------------------------------------------------------ */
152     private void setTzFormatString(final TimeZone JavaDoc tz )
153     {
154         int zIndex = _formatString.indexOf( "ZZZ" );
155         if( zIndex >= 0 )
156         {
157             String JavaDoc ss1 = _formatString.substring( 0, zIndex );
158             String JavaDoc ss2 = _formatString.substring( zIndex+3 );
159             int tzOffset = tz.getRawOffset();
160             
161             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(_formatString.length()+10);
162             sb.append(ss1);
163             sb.append("'");
164             if( tzOffset >= 0 )
165                 sb.append( '+' );
166             else
167             {
168                 tzOffset = -tzOffset;
169                 sb.append( '-' );
170             }
171             
172             int raw = tzOffset / (1000*60); // Convert to seconds
173
int hr = raw / 60;
174             int min = raw % 60;
175             
176             if( hr < 10 )
177                 sb.append( '0' );
178             sb.append( hr );
179             if( min < 10 )
180                 sb.append( '0' );
181             sb.append( min );
182             sb.append( '\'' );
183             
184             sb.append(ss2);
185             _tzFormatString=sb.toString();
186         }
187         else
188             _tzFormatString=_formatString;
189         setMinFormatString();
190     }
191
192     
193     /* ------------------------------------------------------------ */
194     private void setMinFormatString()
195     {
196         int i = _tzFormatString.indexOf("ss.SSS");
197         int l = 6;
198         if (i>=0)
199             _millis=true;
200         else
201         {
202             i = _tzFormatString.indexOf("ss");
203             l=2;
204         }
205         
206         // Build a formatter that formats a second format string
207
// Have to replace @ with ' later due to bug in SimpleDateFormat
208
String JavaDoc ss1=_tzFormatString.substring(0,i);
209         String JavaDoc ss2=_tzFormatString.substring(i+l);
210         _minFormatString =ss1+(_millis?"'ss.SSS'":"'ss'")+ss2;
211     }
212
213     /* ------------------------------------------------------------ */
214     /** Format a date according to our stored formatter.
215      * @param inDate
216      * @return Formatted date
217      */

218     public synchronized String JavaDoc format(Date JavaDoc inDate)
219     {
220         return format(inDate.getTime());
221     }
222     
223     /* ------------------------------------------------------------ */
224     /** Format a date according to our stored formatter.
225      * @param inDate
226      * @return Formatted date
227      */

228     public synchronized String JavaDoc format(long inDate)
229     {
230         long seconds = inDate / 1000;
231
232         // Is it not suitable to cache?
233
if (seconds<_lastSeconds ||
234             _lastSeconds>0 && seconds>_lastSeconds+__hitWindow)
235         {
236             // It's a cache miss
237
_misses++;
238             if (_misses<__MaxMisses)
239             {
240                 Date JavaDoc d = new Date JavaDoc(inDate);
241                 return _tzFormat.format(d);
242             }
243         }
244         else if (_misses>0)
245             _misses--;
246                                           
247         // Check if we are in the same second
248
// and don't care about millis
249
if (_lastSeconds==seconds && !_millis)
250             return _lastResult;
251
252         Date JavaDoc d = new Date JavaDoc(inDate);
253         
254         // Check if we need a new format string
255
long minutes = seconds/60;
256         if (_lastMinutes != minutes)
257         {
258             _lastMinutes = minutes;
259             _secFormatString=_minFormat.format(d);
260
261             int i;
262             int l;
263             if (_millis)
264             {
265                 i=_secFormatString.indexOf("ss.SSS");
266                 l=6;
267             }
268             else
269             {
270                 i=_secFormatString.indexOf("ss");
271                 l=2;
272             }
273             _secFormatString0=_secFormatString.substring(0,i);
274             _secFormatString1=_secFormatString.substring(i+l);
275         }
276
277         // Always format if we get here
278
_lastSeconds = seconds;
279         StringBuffer JavaDoc sb=new StringBuffer JavaDoc(_secFormatString.length());
280         synchronized(sb)
281         {
282             sb.append(_secFormatString0);
283             int s=(int)(seconds%60);
284             if (s<10)
285                 sb.append('0');
286             sb.append(s);
287             if (_millis)
288             {
289                 long millis = inDate%1000;
290                 if (millis<10)
291                     sb.append(".00");
292                 else if (millis<100)
293                     sb.append(".0");
294                 else
295                     sb.append('.');
296                 sb.append(millis);
297             }
298             sb.append(_secFormatString1);
299             _lastResult=sb.toString();
300         }
301                 
302         return _lastResult;
303     }
304
305     /* ------------------------------------------------------------ */
306     /** Format to string buffer.
307      * @param inDate Date the format
308      * @param buffer StringBuffer
309      */

310     public void format(long inDate, StringBuffer JavaDoc buffer)
311     {
312         buffer.append(format(inDate));
313     }
314     
315     /* ------------------------------------------------------------ */
316     /** Get the format.
317      */

318     public SimpleDateFormat JavaDoc getFormat()
319     {
320         return _minFormat;
321     }
322
323     /* ------------------------------------------------------------ */
324     public String JavaDoc getFormatString()
325     {
326         return _formatString;
327     }
328     
329 }
330
Popular Tags