KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > datetime > formatters > DefaultFormatter


1 package jodd.datetime.formatters;
2
3 import jodd.datetime.DateTimeStamp;
4 import jodd.datetime.JDateTime;
5 import jodd.datetime.JdtFormatter;
6 import jodd.datetime.JdtNames;
7 import jodd.format.Format;
8
9 /**
10  * Default formatter used for getting and setting date/time information to
11  * and from strings.<p>
12  *
13  * For setting date and time, default formatter parses input String against
14  * specified template. It extracts parts of input string upon patterns
15  * and then each part is converted to a number for a date/time information.
16  * It doesn't ignore any non-number charater. If conversion fails,
17  * <code>null</code> is returned. Translations from String are done by Java.
18  * <p>
19  *
20  * Getting date time is also user firendly. Specified template may not only
21  * contains patterns but also any text. To remove errors in decoding when
22  * text may be reckognized as one of patterns, template text may be quoted
23  * with the ' sign. Double ' quote in the text will be decoded as single
24  * quote. <p>
25  *
26  * Bellow is the list of the patterns that may be used in templates. This
27  * list enhances ISO 8601 standard. Patterns notted with + sign are used for
28  * settings, all patterns are used for gettings.
29  *
30  * <ul>
31  * <li>YYYY + year</li>
32  * <li>MM + month</li>
33  * <li>DD + day of month</li>
34  * <li>D - day of week</li>
35  * <li>MML - month long name</li>
36  * <li>MMS - month short name</li>
37  * <li>DL - day of week long name</li>
38  * <li>DS - day of week short name</li>
39  * <li>hh + hour</li>
40  * <li>mm + minute</li>
41  * <li>ss + seconds (no milliseconds)</li>
42  * <li>mss + milliseconds</li>
43  * <li>ss.mss + seconds.milliseconds</li>
44  * <li></li>DDD - day of year</li>
45  * <li>WW - week of year</li>
46  * <li>WWW - week of year with 'W' prefix</li>
47  * <li>W - week of month</li>
48  * </ul>
49  */

50 public class DefaultFormatter implements JdtFormatter {
51
52     /**
53      * Array of date/time format patterns according to ISO-8601 standard enhanced
54      * with custom patterns.
55      * <p>
56      *
57      * 'L' suffix is used for long names and 'S' is used for short names text.
58      * <p>
59      *
60      * Warnings:<br>
61      * 1. order of the array elements is IMPORTANT!<br>
62      * 2. the longest match is returned.
63      * 3. patterns that have '+' are used by set(). all patterns are used by get().
64      */

65     private final char[][] formc = {
66         "YYYY".toCharArray(), // 0 + year
67
"MM".toCharArray(), // 1 + month
68
"DD".toCharArray(), // 2 + day of month
69
"D".toCharArray(), // 3 - day of week
70
"MML".toCharArray(), // 4 - month long name
71
"MMS".toCharArray(), // 5 - month short name
72
"DL".toCharArray(), // 6 - day of week long name
73
"DS".toCharArray(), // 7 - day of week short name
74
"hh".toCharArray(), // 8 + hour
75
"mm".toCharArray(), // 9 + minute
76
"ss".toCharArray(), // 10 + seconds (no milliseconds)
77
"mss".toCharArray(), // 11 + milliseconds
78
"ss.mss".toCharArray(), // 12 + seconds.milliseconds
79
"DDD".toCharArray(), // 13 - day of year
80
"WW".toCharArray(), // 14 - week of year
81
"WWW".toCharArray(), // 15 - week of year with 'W' prefix
82
"W".toCharArray(), // 16 - week of month
83
};
84
85     private int findPattern(char[] frmtc, int i) {
86         int frmtc_len = frmtc.length;
87         boolean match = false;
88         int n, lastn = -1;
89         int maxLen = 0;
90         for (n = 0; n < formc.length; n++) {
91             char[] curr = formc[n]; // current pattern from the pattern list
92
if (i > frmtc_len - curr.length) {
93                 continue;
94             }
95             match = true;
96             int delta = 0;
97             while (delta < curr.length) { // match given pattern
98
if (curr[delta] != frmtc[i + delta]) {
99                     match = false; // no match, goto next
100
break;
101                 }
102                 delta++;
103             }
104             if (match == true) { // match
105
if (formc[n].length > maxLen) { // find longest match
106
lastn = n;
107                     maxLen = formc[n].length;
108                 }
109             }
110         }
111         return lastn;
112     }
113
114
115     private static final char QUOTE = '\'';
116
117     /**
118      * Returns date as String in given format. Used by JDateTime for formatting
119      * the string that represents date/time information.
120      *
121      * @param jdt JDateTime instance
122      * @param frmt format
123      *
124      * @return date string in given format
125      */

126     public String get(JDateTime jdt, String frmt) {
127         char[] frmtc = frmt.toCharArray();
128         int frmtc_len = frmtc.length;
129         StringBuffer result = new StringBuffer(frmtc_len);
130
131         int i = 0;
132         while (i < frmtc_len) {
133             
134             if (frmtc[i] == QUOTE) { // quote founded
135
int end = i + 1;
136                 while (end < frmtc_len) {
137                     if (frmtc[end] == QUOTE) { // second quote founded
138
if (end + 1 < frmtc_len) {
139                             end++;
140                             if (frmtc[end] == QUOTE) { // skip double quotes
141
result.append(QUOTE); // and continue
142
} else {
143                                 break;
144                             }
145                         }
146                     } else {
147                         result.append(frmtc[end]);
148                     }
149                     end++;
150                 }
151                 i = end;
152                 continue; // end of quoted string, continue the main loop
153
}
154
155             int n = findPattern(frmtc, i);
156             if (n != -1) { // pattern founded
157
JdtNames gds = jdt.getNames();
158                 switch (n) {
159                     case 0:
160                         result.append(Format.sprintf("%~04i", jdt.getYear()));
161                         break;
162                     case 1:
163                         result.append(Format.sprintf("%02i", jdt.getMonth()));
164                         break;
165                     case 2:
166                         result.append(Format.sprintf("%02i", jdt.getDay()));
167                         break;
168                     case 3:
169                         result.append(jdt.getDayOfWeek());
170                         break;
171                     case 4:
172                         result.append(gds.getMonths()[jdt.getMonth() - 1]);
173                         break;
174                     case 5:
175                         result.append(gds.getShortMonths()[jdt.getMonth() - 1]);
176                         break;
177                     case 6:
178                         result.append(gds.getDaysOfWeek()[jdt.getDayOfWeek() - 1]);
179                         break;
180                     case 7:
181                         result.append(gds.getShortDaysOfWeek()[jdt.getDayOfWeek() - 1]);
182                         break;
183                     case 8:
184                         result.append(Format.sprintf("%02d", jdt.getHour()));
185                         break;
186                     case 9:
187                         result.append(Format.sprintf("%02d", jdt.getMinute()));
188                         break;
189                     case 10:
190                         result.append(Format.sprintf("%02d", (int)jdt.getSecond()));
191                         break;
192                     case 11:
193                         result.append(Format.sprintf("%02d", jdt.getMillisecond()));
194                         break;
195                     case 12:
196                         result.append(Format.sprintf("%06.3f", jdt.getSecond()));
197                         break;
198                     case 13:
199                         result.append(Format.sprintf("%03d", jdt.getDayOfYear()));
200                         break;
201                     case 14:
202                         result.append(Format.sprintf("%02d", jdt.getWeekOfYear()));
203                         break;
204                     case 15:
205                         result.append(Format.sprintf("W%02d", jdt.getWeekOfYear()));
206                         break;
207                     case 16:
208                         result.append(jdt.getWeekOfMonth());
209                         break;
210                 }
211                 i += formc[n].length;
212             } else {
213                 result.append(frmtc[i]);
214                 i++;
215             }
216         }
217         return result.toString();
218     }
219
220
221     /**
222      * Sets time from the string using template. Used by JDateTime for setting
223      * new date/time from the string. But it is also used for validating if some
224      * string represents a valid date.
225      * <p>
226      *
227      * @param s String that contains time
228      * @param t template
229      *
230      * @return DateTimeStamp instance or <code>null</code> if error during conversion
231      * occured
232      */

233     public DateTimeStamp set(String s, String t) {
234         char[] sc = s.toCharArray();
235         char[] tc = t.toCharArray();
236
237         int i = 0;
238         int j = 0;
239         int slen = s.length();
240         int tlen = t.length();
241
242         int year = 0, hour = 0, minute = 0;
243         int month = 1, day = 1;
244         double second = 0.0;
245
246         while (true) {
247             int n = findPattern(tc, i);
248             if (n != -1) { // pattern founded
249
i += formc[n].length;
250                 StringBuffer w = new StringBuffer();
251                 char next = 0xFFFF;
252                 if (i < tlen) {
253                     next = tc[i]; // next = delimeter
254
}
255                 while ((j < slen) && (sc[j] != next)) {
256                     w.append(sc[j]);
257                     j++;
258                 }
259                 try {
260                     String ws = w.toString();
261                     int v = 0;
262                     double vd = 0;
263                     if (n != 12) { // not double
264
v = Integer.parseInt(ws);
265                         if (n == 11) {
266                             vd = 1.0;
267                             for (int u = 0; u < ws.length(); u++) {
268                                 vd *= 10.0;
269                             }
270                         }
271                     } else { // double
272
vd = Double.parseDouble(ws);
273                         vd += 1e-9;
274                     }
275                     switch (n) {
276                         case 0: year = v; break;
277                         case 1: month = v; break;
278                         case 2: day = v; break;
279                         case 8: hour = v; break;
280                         case 9: minute = v; break;
281                         case 10: second += v; break;
282                         case 11: second += v/vd; break;
283                         case 12: second = vd; break;
284                     }
285                 } catch (NumberFormatException nfe) {
286                     return null;
287                 }
288             } else {
289                 if (tc[i] == sc[j]) {
290                     j++;
291                 }
292                 i++;
293             }
294             if ((i == tlen) || (j == slen)) {
295                 break;
296             }
297         }
298         return new DateTimeStamp(year, month, day, hour, minute, second);
299     }
300 }
301
Popular Tags