KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > util > Strftime


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.catalina.util;
19
20 import java.text.SimpleDateFormat JavaDoc;
21 import java.util.Properties JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Locale JavaDoc;
24 import java.util.TimeZone JavaDoc;
25
26 /**
27  * Converts dates to strings using the same format specifiers as strftime
28  *
29  * Note: This does not mimic strftime perfectly. Certain strftime commands,
30  * are not supported, and will convert as if they were literals.
31  *
32  * Certain complicated commands, like those dealing with the week of the year
33  * probably don't have exactly the same behavior as strftime.
34  *
35  * These limitations are due to use SimpleDateTime. If the conversion was done
36  * manually, all these limitations could be eliminated.
37  *
38  * The interface looks like a subset of DateFormat. Maybe someday someone will make this class
39  * extend DateFormat.
40  *
41  * @author Bip Thelin
42  * @author Dan Sandberg
43  * @version $Revision: 467222 $, $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
44  */

45 public class Strftime {
46     protected static Properties JavaDoc translate;
47     protected SimpleDateFormat JavaDoc simpleDateFormat;
48
49     /**
50      * Initialize our pattern translation
51      */

52     static {
53         translate = new Properties JavaDoc();
54         translate.put("a","EEE");
55         translate.put("A","EEEE");
56         translate.put("b","MMM");
57         translate.put("B","MMMM");
58         translate.put("c","EEE MMM d HH:mm:ss yyyy");
59
60         //There's no way to specify the century in SimpleDateFormat. We don't want to hard-code
61
//20 since this could be wrong for the pre-2000 files.
62
//translate.put("C", "20");
63
translate.put("d","dd");
64         translate.put("D","MM/dd/yy");
65         translate.put("e","dd"); //will show as '03' instead of ' 3'
66
translate.put("F","yyyy-MM-dd");
67         translate.put("g","yy");
68         translate.put("G","yyyy");
69         translate.put("H","HH");
70         translate.put("h","MMM");
71         translate.put("I","hh");
72         translate.put("j","DDD");
73         translate.put("k","HH"); //will show as '07' instead of ' 7'
74
translate.put("l","hh"); //will show as '07' instead of ' 7'
75
translate.put("m","MM");
76         translate.put("M","mm");
77         translate.put("n","\n");
78         translate.put("p","a");
79         translate.put("P","a"); //will show as pm instead of PM
80
translate.put("r","hh:mm:ss a");
81         translate.put("R","HH:mm");
82         //There's no way to specify this with SimpleDateFormat
83
//translate.put("s","seconds since ecpoch");
84
translate.put("S","ss");
85         translate.put("t","\t");
86         translate.put("T","HH:mm:ss");
87         //There's no way to specify this with SimpleDateFormat
88
//translate.put("u","day of week ( 1-7 )");
89

90         //There's no way to specify this with SimpleDateFormat
91
//translate.put("U","week in year with first sunday as first day...");
92

93         translate.put("V","ww"); //I'm not sure this is always exactly the same
94

95         //There's no way to specify this with SimpleDateFormat
96
//translate.put("W","week in year with first monday as first day...");
97

98         //There's no way to specify this with SimpleDateFormat
99
//translate.put("w","E");
100
translate.put("X","HH:mm:ss");
101         translate.put("x","MM/dd/yy");
102         translate.put("y","yy");
103         translate.put("Y","yyyy");
104         translate.put("Z","z");
105         translate.put("z","Z");
106         translate.put("%","%");
107     }
108
109
110     /**
111      * Create an instance of this date formatting class
112      *
113      * @see #Strftime( String, Locale )
114      */

115     public Strftime( String JavaDoc origFormat ) {
116         String JavaDoc convertedFormat = convertDateFormat( origFormat );
117         simpleDateFormat = new SimpleDateFormat JavaDoc( convertedFormat );
118     }
119
120     /**
121      * Create an instance of this date formatting class
122      *
123      * @param origFormat the strftime-style formatting string
124      * @param locale the locale to use for locale-specific conversions
125      */

126     public Strftime( String JavaDoc origFormat, Locale JavaDoc locale ) {
127         String JavaDoc convertedFormat = convertDateFormat( origFormat );
128         simpleDateFormat = new SimpleDateFormat JavaDoc( convertedFormat, locale );
129     }
130
131     /**
132      * Format the date according to the strftime-style string given in the constructor.
133      *
134      * @param date the date to format
135      * @return the formatted date
136      */

137     public String JavaDoc format( Date JavaDoc date ) {
138         return simpleDateFormat.format( date );
139     }
140
141     /**
142      * Get the timezone used for formatting conversions
143      *
144      * @return the timezone
145      */

146     public TimeZone JavaDoc getTimeZone() {
147         return simpleDateFormat.getTimeZone();
148     }
149
150     /**
151      * Change the timezone used to format dates
152      *
153      * @see SimpleDateFormat#setTimeZone
154      */

155     public void setTimeZone( TimeZone JavaDoc timeZone ) {
156         simpleDateFormat.setTimeZone( timeZone );
157     }
158
159     /**
160      * Search the provided pattern and get the C standard
161      * Date/Time formatting rules and convert them to the
162      * Java equivalent.
163      *
164      * @param pattern The pattern to search
165      * @return The modified pattern
166      */

167     protected String JavaDoc convertDateFormat( String JavaDoc pattern ) {
168         boolean inside = false;
169         boolean mark = false;
170         boolean modifiedCommand = false;
171
172         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
173
174         for(int i = 0; i < pattern.length(); i++) {
175             char c = pattern.charAt(i);
176
177             if ( c=='%' && !mark ) {
178                 mark=true;
179             } else {
180                 if ( mark ) {
181                     if ( modifiedCommand ) {
182                         //don't do anything--we just wanted to skip a char
183
modifiedCommand = false;
184                         mark = false;
185                     } else {
186                         inside = translateCommand( buf, pattern, i, inside );
187                         //It's a modifier code
188
if ( c=='O' || c=='E' ) {
189                             modifiedCommand = true;
190                         } else {
191                             mark=false;
192                         }
193                     }
194                 } else {
195                     if ( !inside && c != ' ' ) {
196                         //We start a literal, which we need to quote
197
buf.append("'");
198                         inside = true;
199                     }
200                     
201                     buf.append(c);
202                 }
203             }
204         }
205
206         if ( buf.length() > 0 ) {
207             char lastChar = buf.charAt( buf.length() - 1 );
208
209             if( lastChar!='\'' && inside ) {
210                 buf.append('\'');
211             }
212         }
213         return buf.toString();
214     }
215
216     protected String JavaDoc quote( String JavaDoc str, boolean insideQuotes ) {
217         String JavaDoc retVal = str;
218         if ( !insideQuotes ) {
219             retVal = '\'' + retVal + '\'';
220         }
221         return retVal;
222     }
223
224     /**
225      * Try to get the Java Date/Time formatting associated with
226      * the C standard provided.
227      *
228      * @param buf The buffer
229      * @param pattern The date/time pattern
230      * @param index The char index
231      * @param oldInside Flag value
232      * @return True if new is inside buffer
233      */

234     protected boolean translateCommand( StringBuffer JavaDoc buf, String JavaDoc pattern, int index, boolean oldInside ) {
235         char firstChar = pattern.charAt( index );
236         boolean newInside = oldInside;
237
238         //O and E are modifiers, they mean to present an alternative representation of the next char
239
//we just handle the next char as if the O or E wasn't there
240
if ( firstChar == 'O' || firstChar == 'E' ) {
241             if ( index + 1 < pattern.length() ) {
242                 newInside = translateCommand( buf, pattern, index + 1, oldInside );
243             } else {
244                 buf.append( quote("%" + firstChar, oldInside ) );
245             }
246         } else {
247             String JavaDoc command = translate.getProperty( String.valueOf( firstChar ) );
248             
249             //If we don't find a format, treat it as a literal--That's what apache does
250
if ( command == null ) {
251                 buf.append( quote( "%" + firstChar, oldInside ) );
252             } else {
253                 //If we were inside quotes, close the quotes
254
if ( oldInside ) {
255                     buf.append( '\'' );
256                 }
257                 buf.append( command );
258                 newInside = false;
259             }
260         }
261         return newInside;
262     }
263 }
264
Popular Tags