KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dbforms > util > TimeUtil


1 /*
2  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/TimeUtil.java,v 1.23 2005/02/18 11:47:25 hkollmann Exp $
3  * $Revision: 1.23 $
4  * $Date: 2005/02/18 11:47:25 $
5  *
6  * DbForms - a Rapid Application Development Framework
7  * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */

23
24 package org.dbforms.util;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.apache.regexp.RE;
30 import org.apache.regexp.RESyntaxException;
31
32 /**
33  * Helper classes for dealing with time values
34  *
35  */

36 import java.text.SimpleDateFormat JavaDoc;
37
38 import java.util.Calendar JavaDoc;
39 import java.util.Date JavaDoc;
40 import java.util.GregorianCalendar JavaDoc;
41 import java.util.TimeZone JavaDoc;
42
43
44
45 /**
46  * DOCUMENT ME!
47  *
48  * @version $Revision: 1.23 $
49  * @author $author$
50  */

51 public class TimeUtil {
52    private static Log logCat = LogFactory.getLog(TimeUtil.class.getName());
53    static final int SECSPERDAY = 24 * 60 * 60;
54    private static String JavaDoc reISO8601 = "(\\d\\d\\d\\d)(-(\\d\\d)(-(\\d\\d))?)?"
55                                       + "([T| ]?"
56                                       + "(\\d\\d):(\\d\\d)(:((\\d\\d)(\\.(\\d+))?)?)?"
57                                       + "(Z|([+-]\\d\\d:\\d\\d)|([A-Z]{3}))?)?";
58
59    /**
60     * Reformats seconds to time string with format: dd:hh:mm:ss
61     *
62     * @param seconds string to format
63     *
64     * @return String
65     */

66    public static final String JavaDoc seconds2String(String JavaDoc seconds) {
67       if (Util.isNull(seconds)) {
68          return "";
69       } else {
70          return seconds2String(Integer.valueOf(seconds));
71       }
72    }
73
74
75    /**
76     * Reformats seconds to time string with format: dd:hh:mm:ss
77     *
78     * @param seconds Integer to format
79     *
80     * @return String
81     */

82    public static final String JavaDoc seconds2String(Integer JavaDoc seconds) {
83       return seconds2String(seconds.intValue());
84    }
85
86
87    /**
88     * Reformats seconds to time string with format: dd:hh:mm:ss
89     *
90     * @param seconds string to format
91     *
92     * @return String
93     */

94    public static final String JavaDoc seconds2String(Long JavaDoc seconds) {
95       return seconds2String(seconds.longValue());
96    }
97
98
99    /**
100     * Reformats seconds to time string with format: dd:hh:mm:ss
101     *
102     * @param seconds string to format
103     *
104     * @return String
105     */

106    public static final String JavaDoc seconds2String(long seconds) {
107       long d;
108       long h;
109       long m;
110       String JavaDoc zeit;
111       d = (seconds / SECSPERDAY);
112       seconds = seconds - (d * SECSPERDAY);
113       h = seconds / (60 * 60);
114       seconds = seconds - (h * 60 * 60);
115       m = seconds / 60;
116       seconds = seconds - (m * 60);
117
118       if (d > 0) {
119          Object JavaDoc[] o = {
120                          new Long JavaDoc(d),
121                          new Long JavaDoc(h),
122                          new Long JavaDoc(m),
123                          new Long JavaDoc(seconds)
124                       };
125          zeit = Util.sprintf("%i:%02i:%02i:%02i", o);
126       } else {
127          Object JavaDoc[] o = {
128                          new Long JavaDoc(h),
129                          new Long JavaDoc(m),
130                          new Long JavaDoc(seconds)
131                       };
132          zeit = Util.sprintf("%i:%02i:%02i", o);
133       }
134
135       return zeit;
136    }
137
138
139    /**
140     * finds the end of the given day
141     *
142     * @param d date of which end should be find
143     *
144     * @return end of the day
145     */

146    public static Date JavaDoc findEndOfDay(Date JavaDoc d) {
147       Calendar JavaDoc cal = Calendar.getInstance();
148       cal.setTime(d);
149       cal.set(Calendar.HOUR_OF_DAY, 0);
150       cal.set(Calendar.MINUTE, 0);
151       cal.set(Calendar.SECOND, 0);
152       cal.add(Calendar.DAY_OF_MONTH, 1);
153
154       return cal.getTime();
155    }
156
157
158    /**
159     * Tries to parse a String into a Calendar objectvalue. String mustn't a full date,
160     * parts are enough. Parsing will set missing parts to default values
161     *
162     * @param loc locale to use
163     * @param format java format string for date/time
164     * @param s string to be parsed
165     *
166     * @return the parsed date
167     */

168    public static Calendar JavaDoc parseDate(final SimpleDateFormat JavaDoc format,
169                                     String JavaDoc s) {
170       StringBuffer JavaDoc sDate = new StringBuffer JavaDoc();
171       StringBuffer JavaDoc sTime = new StringBuffer JavaDoc();
172       StringBuffer JavaDoc fDate = new StringBuffer JavaDoc();
173       StringBuffer JavaDoc fTime = new StringBuffer JavaDoc();
174
175       splitDate(s, sDate, sTime);
176       splitDate(format.toPattern(), fDate, fTime);
177
178       SimpleDateFormat JavaDoc f = (SimpleDateFormat JavaDoc) format.clone();
179       Calendar JavaDoc dDate = saveParseDate(f, fDate.toString(),
180                                              sDate.toString());
181       long date = dDate.getTime()
182                                    .getTime();
183       f.setTimeZone(dDate.getTimeZone());
184
185       long time = saveParseTime(f, fTime.toString(), sTime.toString());
186       long offset = dDate.getTimeZone()
187                          .getRawOffset();
188
189       if (!Util.isNull(sTime.toString())) {
190          time = time + offset;
191       }
192
193       date = date + time;
194
195       Calendar JavaDoc c = format.getCalendar();
196
197       //20040304 JFM: replaced Calendar.setTimeInMillis(long)
198
Date JavaDoc dateAsDate = new Date JavaDoc(date);
199       c.setTime(dateAsDate);
200
201       logCat.info("parsed " + s + " to " + format.format(c.getTime()));
202
203       return c;
204    }
205
206
207    /**
208     * Parses an ISO8601 date format string
209     *
210     * @param s string to be parsed
211     *
212     * @return the parsed date
213     */

214    public static Date JavaDoc parseISO8601Date(String JavaDoc s) {
215       ISO8601 iso = parseISO8601(s);
216
217       if (iso != null) {
218          TimeZone JavaDoc tz = null;
219
220          // see if setting tz first fixes tz bug
221
if ((iso.tz != null) && !(iso.tz.length() == 0)) {
222             if (iso.tz.equals("Z")) {
223                tz = TimeZone.getTimeZone("GMT");
224             } else if (iso.tz.length() == 3) {
225                tz = TimeZone.getTimeZone(iso.tz);
226             } else {
227                tz = TimeZone.getTimeZone("GMT" + iso.tz);
228             }
229          }
230
231          Calendar JavaDoc cal = new GregorianCalendar JavaDoc(iso.year, iso.month - 1, iso.day,
232                                               iso.hour, iso.min, iso.sec);
233
234          if (tz != null) {
235             cal.setTimeZone(tz);
236          }
237
238          return cal.getTime();
239       }
240
241       // if iso
242
return null;
243    }
244
245
246    private static ISO8601 parseISO8601(String JavaDoc s) {
247       // ISO 8601 datetime: http://www.w3.org/TR/NOTE-datetime
248
// e.g. 1997-07-16T19:20:30.45+01:00
249
// additions: "T" can be a space, TZ can be a three-char code, TZ can be missing
250
try {
251          RE re = new RE(reISO8601);
252
253          if (re.match(s)) {
254             ISO8601 iso = new ISO8601();
255             iso.year = toInt(re.getParen(1));
256             iso.month = toInt(re.getParen(3));
257             iso.day = toInt(re.getParen(5));
258             iso.hour = toInt(re.getParen(7));
259             iso.min = toInt(re.getParen(8));
260             iso.sec = toInt(re.getParen(11));
261             iso.frac = toInt(re.getParen(13));
262             iso.tz = re.getParen(14);
263
264             return iso;
265          }
266       }
267       // try
268
catch (RESyntaxException ree) {
269          ree.printStackTrace();
270       }
271
272       return null;
273    }
274
275
276    private static Calendar JavaDoc saveParseDate(final SimpleDateFormat JavaDoc format,
277                                          String JavaDoc formatString,
278                                          String JavaDoc s)
279                                   throws NumberFormatException JavaDoc {
280       Date JavaDoc d = null;
281       Calendar JavaDoc cal;
282       Calendar JavaDoc now = Calendar.getInstance();
283
284       if (!Util.isNull(s)) {
285          if (!Util.isNull(formatString)) {
286             format.applyPattern(formatString);
287          }
288
289          try {
290             d = format.parse(s);
291          } catch (Exception JavaDoc e) {
292             logCat.error(e);
293
294             // Make parsing more tolerant - try sql standard format too
295
SimpleDateFormat JavaDoc f = (SimpleDateFormat JavaDoc) format.clone();
296             f.applyPattern("yyyy-MM-dd");
297
298             try {
299                d = f.parse(s);
300             } catch (Exception JavaDoc ex) {
301                logCat.error(ex);
302             }
303          }
304
305          cal = format.getCalendar();
306
307          if (d != null) {
308             cal.setTime(d);
309          } else {
310             synchronized (cal) {
311                try {
312                   // HKK: I do not know why this is necessary, but if you do not wait
313
// the calender HOUR_OF_DAY maybe unset...
314
cal.wait(5);
315                } catch (Exception JavaDoc ex) {
316                   logCat.error(ex);
317                }
318             }
319          }
320
321          if (!cal.isSet(Calendar.DAY_OF_MONTH)
322                    && !cal.isSet(Calendar.MONTH)
323                    && !cal.isSet(Calendar.YEAR)) {
324             throw new NumberFormatException JavaDoc("wrong date format");
325          }
326
327          if (!cal.isSet(Calendar.DAY_OF_MONTH)) {
328             cal.set(Calendar.DAY_OF_MONTH, now.get(Calendar.DAY_OF_MONTH));
329          }
330
331          if (!cal.isSet(Calendar.MONTH)) {
332             cal.set(Calendar.MONTH, now.get(Calendar.MONTH));
333          }
334
335          if (!cal.isSet(Calendar.YEAR)) {
336             cal.set(Calendar.YEAR, now.get(Calendar.YEAR));
337          }
338
339          if (cal.get(Calendar.YEAR) < 30) {
340             cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 2000);
341          } else if (cal.get(Calendar.YEAR) < 100) {
342             cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 1900);
343          }
344       } else {
345          cal = now;
346       }
347
348       cal.set(Calendar.HOUR_OF_DAY, 0);
349       cal.set(Calendar.MINUTE, 0);
350       cal.set(Calendar.SECOND, 0);
351
352       return cal;
353    }
354
355
356    private static synchronized long saveParseTime(final SimpleDateFormat JavaDoc format,
357                                                   String JavaDoc formatString,
358                                                   String JavaDoc s) {
359       Date JavaDoc d = null;
360
361       if (!Util.isNull(s)) {
362          if (!Util.isNull(formatString)) {
363             format.applyPattern(formatString);
364          }
365
366          try {
367             d = format.parse(s);
368          } catch (Exception JavaDoc e) {
369             logCat.error(e);
370
371             // Make parsing more tolerant - try 24 hour formats too
372
SimpleDateFormat JavaDoc f = (SimpleDateFormat JavaDoc) format.clone();
373             f.applyPattern("HH:mm:ss");
374
375             try {
376                d = f.parse(s);
377             } catch (Exception JavaDoc ex) {
378                logCat.error(ex);
379             }
380          }
381
382          Calendar JavaDoc cal = format.getCalendar();
383
384          if (d != null) {
385             cal.setTime(d);
386          } else {
387             synchronized (cal) {
388                try {
389                   // HKK: I do not know why this is necessary, but if you do not wait
390
// the calender HOUR_OF_DAY maybe unset...
391
cal.wait(5);
392                } catch (Exception JavaDoc ex) {
393                   logCat.error(ex);
394                }
395             }
396          }
397
398          if (!cal.isSet(Calendar.HOUR_OF_DAY)
399                    && !cal.isSet(Calendar.MINUTE)
400                    && !cal.isSet(Calendar.SECOND)) {
401             throw new NumberFormatException JavaDoc("wrong time format");
402          }
403
404          if (!cal.isSet(Calendar.HOUR_OF_DAY)) {
405             cal.set(Calendar.HOUR_OF_DAY, 0);
406          }
407
408          if (!cal.isSet(Calendar.MINUTE)) {
409             cal.set(Calendar.MINUTE, 0);
410          }
411
412          if (!cal.isSet(Calendar.SECOND)) {
413             cal.set(Calendar.SECOND, 0);
414          }
415
416          return cal.getTime()
417                    .getTime();
418       }
419
420       return 0;
421    }
422
423
424    public static void splitDate(final String JavaDoc format,
425                                  StringBuffer JavaDoc sDate,
426                                  StringBuffer JavaDoc sTime) {
427       sDate.setLength(0);
428       sTime.setLength(0);
429
430       int i = format.lastIndexOf(':');
431
432       if (i > -1) {
433          i = format.lastIndexOf(' ', i);
434
435          if (i > -1) {
436             sDate.append(format.substring(0, i));
437             sTime.append(format.substring(i + 1));
438          } else {
439             sTime.append(format);
440          }
441       } else {
442          sDate.append(format);
443       }
444    }
445
446
447    private static int toInt(String JavaDoc x) {
448       if (x == null) {
449          return 0;
450       }
451
452       try {
453          return Integer.parseInt(x);
454       } catch (NumberFormatException JavaDoc e) {
455          return 0;
456       }
457    }
458
459    /**
460     * Parses an ISO8601 date format string
461     *
462     */

463    private static class ISO8601 {
464       public String JavaDoc tz;
465       public int day;
466       public int frac;
467       public int hour;
468       public int min;
469       public int month;
470       public int sec;
471       public int year;
472    }
473 }
474
Popular Tags