001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.util;
046:
047: import java.text.DateFormat;
048: import java.text.ParseException;
049: import java.text.SimpleDateFormat;
050: import java.util.Date;
051:
052: /**
053: * Date formatting and parsing utilities. This is not a threadsafe class. Each
054: * thread must call the {@link #getInstance} method to obtain its own dedicated
055: * instance.
056: *
057: * @author Anthony Eden
058: * @author Adrian Price
059: */
060: public final class DateUtilities {
061: public static final String DEFAULT_DATE_FORMAT = CommonConfig
062: .getDefaultDateFormat();
063: private static final String[] _jdk13DefaultFormats = {
064: DEFAULT_DATE_FORMAT, "yyyy-MM-dd'T'HH:mm:ss",
065: // XPDL examples format (yuk).
066: "MM/dd/yyyy hh:mm:ss a",
067: // Alternative format.
068: "yyyy-MM-dd HH:mm:ss z", "yyyy-MM-dd HH:mm:ss",
069: "yyyy-MM-ddZ", };
070: private static final String[] _jdk14DefaultFormats = {
071: // xsd:dateTime / ISO 8601 extended date/time formats as per XML Schema.
072: DEFAULT_DATE_FORMAT, "yyyy-MM-dd'T'HH:mm:ss",
073: // XPDL examples format (yuk).
074: "MM/dd/yyyy hh:mm:ss a",
075: // Alternative format.
076: "yyyy-MM-dd HH:mm:ss z", "yyyy-MM-dd HH:mm:ss",
077: "yyyy-MM-ddZ", "yyyy-MM-dd", };
078: private static final String[] formatStrings;
079: private static final ThreadLocal _tlsInstance = new ThreadLocal();
080: private final DateFormat[] _formats;
081:
082: static {
083: // We don't support pre-JDK1.3 versions.
084: boolean jdk13 = System.getProperty("java.version").startsWith(
085: "1.3");
086: formatStrings = jdk13 ? _jdk13DefaultFormats
087: : _jdk14DefaultFormats;
088: }
089:
090: /**
091: * Get an instance of the DateUtilities class for the current thread.
092: *
093: * @return A DateUtilities instance
094: */
095: public static DateUtilities getInstance() {
096: DateUtilities inst = (DateUtilities) _tlsInstance.get();
097: if (inst == null) {
098: inst = new DateUtilities();
099: _tlsInstance.set(inst);
100: }
101: return inst;
102: }
103:
104: /**
105: * Construct a new DateUtilities class.
106: */
107: private DateUtilities() {
108: _formats = new DateFormat[formatStrings.length];
109: for (int i = 0; i < _formats.length; i++)
110: _formats[i] = new SimpleDateFormat(formatStrings[i]);
111: }
112:
113: public void setFormats(DateFormat[] formats) {
114: System.arraycopy(formats, 0, _formats, 0, _formats.length);
115: }
116:
117: public DateFormat[] getFormats() {
118: return (DateFormat[]) _formats.clone();
119: }
120:
121: /**
122: * Parse the specified date string.
123: *
124: * @param dateString The date string
125: * @return The Date object.
126: * @throws ParseException if the date format is not supported.
127: */
128: public Date parse(String dateString) throws ParseException {
129: for (int i = 0; i < _formats.length; i++) {
130: try {
131: return _formats[i].parse(dateString);
132: } catch (ParseException e) {
133: // do nothing
134: }
135: }
136: throw new ParseException("Unsupported date format: "
137: + dateString, -1);
138: }
139:
140: public String format(Date date) {
141: return date == null ? null : _formats[0].format(date);
142: }
143: }
|