KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > util > RubyDateFormat


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2002 Jan Arne Petersen <jpetersen@uni-bonn.de>
15  * Copyright (C) 2004 Charles O Nutter <headius@headius.com>
16  * Copyright (C) 2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
17  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
18  *
19  * Alternatively, the contents of this file may be used under the terms of
20  * either of the GNU General Public License Version 2 or later (the "GPL"),
21  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
22  * in which case the provisions of the GPL or the LGPL are applicable instead
23  * of those above. If you wish to allow use of your version of this file only
24  * under the terms of either the GPL or the LGPL, and not to allow others to
25  * use your version of this file under the terms of the CPL, indicate your
26  * decision by deleting the provisions above and replace them with the notice
27  * and other provisions required by the GPL or the LGPL. If you do not delete
28  * the provisions above, a recipient may use your version of this file under
29  * the terms of any one of the CPL, the GPL or the LGPL.
30  ***** END LICENSE BLOCK *****/

31 package org.jruby.util;
32
33 import java.text.DateFormat JavaDoc;
34 import java.text.DateFormatSymbols JavaDoc;
35 import java.text.FieldPosition JavaDoc;
36 import java.text.ParsePosition JavaDoc;
37 import java.util.Calendar JavaDoc;
38 import java.util.Date JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.LinkedList JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Locale JavaDoc;
43 import java.util.TimeZone JavaDoc;
44
45 public class RubyDateFormat extends DateFormat JavaDoc {
46     private static final long serialVersionUID = -250429218019023997L;
47
48     private List JavaDoc compiledPattern;
49
50     private DateFormatSymbols JavaDoc formatSymbols;
51
52     private static final int FORMAT_STRING = 0;
53     private static final int FORMAT_WEEK_LONG = 1;
54     private static final int FORMAT_WEEK_SHORT = 2;
55     private static final int FORMAT_MONTH_LONG = 3;
56     private static final int FORMAT_MONTH_SHORT = 4;
57     private static final int FORMAT_DAY = 5;
58     private static final int FORMAT_HOUR = 6;
59     private static final int FORMAT_HOUR_M = 7;
60     private static final int FORMAT_DAY_YEAR = 8;
61     private static final int FORMAT_MINUTES = 9;
62     private static final int FORMAT_MONTH = 10;
63     private static final int FORMAT_MERIDIAN = 11;
64     private static final int FORMAT_SECONDS = 12;
65     private static final int FORMAT_WEEK_YEAR_S = 13;
66     private static final int FORMAT_WEEK_YEAR_M = 14;
67     private static final int FORMAT_DAY_WEEK = 15;
68     private static final int FORMAT_YEAR_LONG = 16;
69     private static final int FORMAT_YEAR_SHORT = 17;
70     private static final int FORMAT_ZONE_OFF = 18;
71     private static final int FORMAT_ZONE_ID = 19;
72
73     private static class Token {
74         private int format;
75         private Object JavaDoc data;
76         
77         public Token(int format) {
78             this(format, null);
79         }
80
81         public Token(int format, Object JavaDoc data) {
82             this.format = format;
83             this.data = data;
84         }
85         
86         /**
87          * Gets the data.
88          * @return Returns a Object
89          */

90         public Object JavaDoc getData() {
91             return data;
92         }
93
94         /**
95          * Gets the format.
96          * @return Returns a int
97          */

98         public int getFormat() {
99             return format;
100         }
101     }
102
103     /**
104      * Constructor for RubyDateFormat.
105      */

106     public RubyDateFormat() {
107         this("", new DateFormatSymbols JavaDoc());
108     }
109
110     public RubyDateFormat(String JavaDoc pattern, Locale JavaDoc aLocale) {
111         this(pattern, new DateFormatSymbols JavaDoc(aLocale));
112     }
113     
114     public RubyDateFormat(String JavaDoc pattern, DateFormatSymbols JavaDoc formatSymbols) {
115         super();
116
117         this.formatSymbols = formatSymbols;
118         applyPattern(pattern);
119     }
120     
121     public void applyPattern(String JavaDoc pattern) {
122         compilePattern(pattern);
123     }
124
125     private void compilePattern(String JavaDoc pattern) {
126         compiledPattern = new LinkedList JavaDoc();
127         
128         int len = pattern.length();
129         for (int i = 0; i < len;) {
130             if (pattern.charAt(i) == '%') {
131                 i++;
132                 switch (pattern.charAt(i)) {
133                     case 'A' :
134                         compiledPattern.add(new Token(FORMAT_WEEK_LONG));
135                         break;
136                     case 'a' :
137                         compiledPattern.add(new Token(FORMAT_WEEK_SHORT));
138                         break;
139                     case 'B' :
140                         compiledPattern.add(new Token(FORMAT_MONTH_LONG));
141                         break;
142                     case 'b' :
143                         compiledPattern.add(new Token(FORMAT_MONTH_SHORT));
144                         break;
145                     case 'c' :
146                         compiledPattern.add(new Token(FORMAT_WEEK_SHORT));
147                         compiledPattern.add(new Token(FORMAT_STRING, " "));
148                         compiledPattern.add(new Token(FORMAT_MONTH_SHORT));
149                         compiledPattern.add(new Token(FORMAT_STRING, " "));
150                         compiledPattern.add(new Token(FORMAT_DAY));
151                         compiledPattern.add(new Token(FORMAT_STRING, " "));
152                         compiledPattern.add(new Token(FORMAT_HOUR));
153                         compiledPattern.add(new Token(FORMAT_STRING, ":"));
154                         compiledPattern.add(new Token(FORMAT_MINUTES));
155                         compiledPattern.add(new Token(FORMAT_STRING, ":"));
156                         compiledPattern.add(new Token(FORMAT_SECONDS));
157                         compiledPattern.add(new Token(FORMAT_STRING, " "));
158                         compiledPattern.add(new Token(FORMAT_YEAR_LONG));
159                         break;
160                     case 'd':
161                         compiledPattern.add(new Token(FORMAT_DAY));
162                         break;
163                     case 'H':
164                         compiledPattern.add(new Token(FORMAT_HOUR));
165                         break;
166                     case 'I':
167                         compiledPattern.add(new Token(FORMAT_HOUR_M));
168                         break;
169                     case 'j':
170                         compiledPattern.add(new Token(FORMAT_DAY_YEAR));
171                         break;
172                     case 'M':
173                         compiledPattern.add(new Token(FORMAT_MINUTES));
174                         break;
175                     case 'm':
176                         compiledPattern.add(new Token(FORMAT_MONTH));
177                         break;
178                     case 'p':
179                         compiledPattern.add(new Token(FORMAT_MERIDIAN));
180                         break;
181                     case 'S':
182                         compiledPattern.add(new Token(FORMAT_SECONDS));
183                         break;
184                     case 'U':
185                         compiledPattern.add(new Token(FORMAT_WEEK_YEAR_S));
186                         break;
187                     case 'W':
188                         compiledPattern.add(new Token(FORMAT_WEEK_YEAR_M));
189                         break;
190                     case 'w':
191                         compiledPattern.add(new Token(FORMAT_DAY_WEEK));
192                         break;
193                     case 'X':
194                         compiledPattern.add(new Token(FORMAT_HOUR));
195                         compiledPattern.add(new Token(FORMAT_STRING, ":"));
196                         compiledPattern.add(new Token(FORMAT_MINUTES));
197                         compiledPattern.add(new Token(FORMAT_STRING, ":"));
198                         compiledPattern.add(new Token(FORMAT_SECONDS));
199                         break;
200                     case 'x':
201                         compiledPattern.add(new Token(FORMAT_MONTH));
202                         compiledPattern.add(new Token(FORMAT_STRING, "/"));
203                         compiledPattern.add(new Token(FORMAT_DAY));
204                         compiledPattern.add(new Token(FORMAT_STRING, "/"));
205                         compiledPattern.add(new Token(FORMAT_YEAR_SHORT));
206                         break;
207                     case 'Y':
208                         compiledPattern.add(new Token(FORMAT_YEAR_LONG));
209                         break;
210                     case 'y':
211                         compiledPattern.add(new Token(FORMAT_YEAR_SHORT));
212                         break;
213                     case 'Z':
214                         compiledPattern.add(new Token(FORMAT_ZONE_ID));
215                         break;
216                     case 'z':
217                         compiledPattern.add(new Token(FORMAT_ZONE_OFF));
218                         break;
219                     case '%':
220                         compiledPattern.add(new Token(FORMAT_STRING, "%"));
221                         break;
222                     default:
223                         compiledPattern.add(new Token(FORMAT_STRING, "%" + pattern.charAt(i)));
224                 }
225                 i++;
226             } else {
227                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
228                 for (;i < len && pattern.charAt(i) != '%'; i++) {
229                     sb.append(pattern.charAt(i));
230                 }
231                 compiledPattern.add(new Token(FORMAT_STRING, sb.toString()));
232             }
233         }
234     }
235
236     /**
237      * @see DateFormat#format(Date, StringBuffer, FieldPosition)
238      */

239     public StringBuffer JavaDoc format(Date JavaDoc date, StringBuffer JavaDoc toAppendTo, FieldPosition JavaDoc fieldPosition) {
240         calendar.setTime(date);
241         calendar.setMinimalDaysInFirstWeek(1);
242         
243         Iterator JavaDoc iter = compiledPattern.iterator();
244         while (iter.hasNext()) {
245             Token token = (Token) iter.next();
246             
247             switch (token.getFormat()) {
248                 case FORMAT_STRING:
249                     toAppendTo.append(token.getData());
250                     break;
251                 case FORMAT_WEEK_LONG:
252                     toAppendTo.append(formatSymbols.getWeekdays()[calendar.get(Calendar.DAY_OF_WEEK)]);
253                     break;
254                 case FORMAT_WEEK_SHORT:
255                     toAppendTo.append(formatSymbols.getShortWeekdays()[calendar.get(Calendar.DAY_OF_WEEK)]);
256                     break;
257                 case FORMAT_MONTH_LONG:
258                     toAppendTo.append(formatSymbols.getMonths()[calendar.get(Calendar.MONTH)]);
259                     break;
260                 case FORMAT_MONTH_SHORT:
261                     toAppendTo.append(formatSymbols.getShortMonths()[calendar.get(Calendar.MONTH)]);
262                     break;
263                 case FORMAT_DAY:
264                     int value = calendar.get(Calendar.DAY_OF_MONTH);
265                     if (value < 10) {
266                         toAppendTo.append('0');
267                     }
268                     toAppendTo.append(value);
269                     break;
270                 case FORMAT_HOUR:
271                     value = calendar.get(Calendar.HOUR_OF_DAY);
272                     if (value < 10) {
273                         toAppendTo.append('0');
274                     }
275                     toAppendTo.append(value);
276                     break;
277                 case FORMAT_HOUR_M:
278                     value = calendar.get(Calendar.HOUR);
279                     if (value < 10) {
280                         toAppendTo.append('0');
281                     }
282                     toAppendTo.append(value);
283                     break;
284                 case FORMAT_DAY_YEAR:
285                     value = calendar.get(Calendar.DAY_OF_YEAR);
286                     if (value < 10) {
287                         toAppendTo.append("00");
288                     } else if (value < 100) {
289                         toAppendTo.append('0');
290                     }
291                     toAppendTo.append(value);
292                     break;
293                 case FORMAT_MINUTES:
294                     value = calendar.get(Calendar.MINUTE);
295                     if (value < 10) {
296                         toAppendTo.append('0');
297                     }
298                     toAppendTo.append(value);
299                     break;
300                 case FORMAT_MONTH:
301                     value = calendar.get(Calendar.MONTH) + 1;
302                     if (value < 10) {
303                         toAppendTo.append('0');
304                     }
305                     toAppendTo.append(value);
306                     break;
307                 case FORMAT_MERIDIAN:
308                     if (calendar.get(Calendar.AM_PM) == Calendar.AM) {
309                         toAppendTo.append("AM");
310                     } else {
311                         toAppendTo.append("PM");
312                     }
313                     break;
314                 case FORMAT_SECONDS:
315                     value = calendar.get(Calendar.SECOND);
316                     if (value < 10) {
317                         toAppendTo.append('0');
318                     }
319                     toAppendTo.append(value);
320                     break;
321                 case FORMAT_WEEK_YEAR_M:
322                     formatWeekYear(Calendar.MONDAY, toAppendTo);
323                     break;
324                     // intentional fall-through
325
case FORMAT_WEEK_YEAR_S:
326                     formatWeekYear(Calendar.SUNDAY, toAppendTo);
327                     break;
328                 case FORMAT_DAY_WEEK:
329                     value = calendar.get(Calendar.DAY_OF_WEEK) - 1;
330                     toAppendTo.append(value);
331                     break;
332                 case FORMAT_YEAR_LONG:
333                     value = calendar.get(Calendar.YEAR);
334                     if (value < 10) {
335                         toAppendTo.append("000");
336                     } else if (value < 100) {
337                         toAppendTo.append("00");
338                     } else if (value < 1000) {
339                         toAppendTo.append('0');
340                     }
341                     toAppendTo.append(value);
342                     break;
343                 case FORMAT_YEAR_SHORT:
344                     value = calendar.get(Calendar.YEAR) % 100;
345                     if (value < 10) {
346                         toAppendTo.append('0');
347                     }
348                     toAppendTo.append(value);
349                     break;
350                 case FORMAT_ZONE_OFF:
351                     value = calendar.getTimeZone().getOffset(calendar.getTimeInMillis());
352                     if (value <= 0) {
353                         toAppendTo.append('+');
354                     } else {
355                         toAppendTo.append('-');
356                     }
357                     value = Math.abs(value);
358                     if (value / 3600000 < 10) {
359                         toAppendTo.append('0');
360                     }
361                     toAppendTo.append(value / 3600000);
362                     value = value % 3600000 / 60000;
363                     if (value < 10) {
364                         toAppendTo.append('0');
365                     }
366                     toAppendTo.append(value);
367                     break;
368                 case FORMAT_ZONE_ID:
369                     toAppendTo.append(calendar.getTimeZone().getDisplayName(calendar.get(Calendar.DST_OFFSET) != 0, TimeZone.SHORT));
370                     break;
371             }
372         }
373
374         return toAppendTo;
375     }
376
377     private void formatWeekYear(int firstDayOfWeek, StringBuffer JavaDoc toAppendTo) {
378         calendar.setFirstDayOfWeek(firstDayOfWeek);
379         int value = calendar.get(Calendar.WEEK_OF_YEAR);
380         if (calendar.get(Calendar.DAY_OF_WEEK) != firstDayOfWeek) {
381             value--;
382         }
383         if (value < 10) {
384             toAppendTo.append('0');
385         }
386         toAppendTo.append(value);
387         calendar.setFirstDayOfWeek(Calendar.SUNDAY);
388     }
389
390     /**
391      * @see DateFormat#parse(String, ParsePosition)
392      */

393     public Date JavaDoc parse(String JavaDoc source, ParsePosition JavaDoc pos) {
394         throw new UnsupportedOperationException JavaDoc();
395     }
396 }
397
Popular Tags