001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.aegis.util.date;
019:
020: import java.text.FieldPosition;
021: import java.text.Format;
022: import java.text.ParsePosition;
023: import java.util.Calendar;
024: import java.util.TimeZone;
025:
026: import javax.xml.datatype.DatatypeConfigurationException;
027: import javax.xml.datatype.DatatypeFactory;
028: import javax.xml.datatype.XMLGregorianCalendar;
029:
030: /**
031: * <p>
032: * An instance of {@link java.text.Format}, which may be used to parse and
033: * format <code>xs:dateTime</code> values.
034: * </p>
035: */
036: public class XsDateTimeFormat extends Format {
037: private static final long serialVersionUID = 3258131340871479609L;
038:
039: final boolean parseDate;
040:
041: final boolean parseTime;
042:
043: XsDateTimeFormat(boolean pParseDate, boolean pParseTime) {
044: parseDate = pParseDate;
045: parseTime = pParseTime;
046: }
047:
048: /**
049: * Creates a new instance.
050: */
051: public XsDateTimeFormat() {
052: this (true, true);
053: }
054:
055: public Object parseObject(String pString,
056: ParsePosition pParsePosition) {
057: if (pString == null) {
058: throw new NullPointerException(
059: "The String argument must not be null.");
060: }
061: if (pParsePosition == null) {
062: throw new NullPointerException(
063: "The ParsePosition argument must not be null.");
064: }
065: int offset = pParsePosition.getIndex();
066: int idxSpc = pString.indexOf(' ', offset);
067: int idxCom = pString.indexOf(',', offset);
068:
069: if (idxCom != -1 && idxCom < idxSpc) {
070: idxSpc = idxCom;
071: }
072: String newVal = null;
073: if (idxSpc == -1) {
074: newVal = pString.substring(offset);
075: } else {
076: newVal = pString.substring(offset, idxSpc);
077: }
078: DatatypeFactory factory;
079: try {
080: factory = DatatypeFactory.newInstance();
081: XMLGregorianCalendar cal = factory
082: .newXMLGregorianCalendar(newVal);
083:
084: pParsePosition.setIndex(idxSpc);
085: return cal.toGregorianCalendar();
086: } catch (DatatypeConfigurationException e) {
087: pParsePosition.setErrorIndex(offset);
088: }
089: return null;
090: }
091:
092: private void append(StringBuffer pBuffer, int pNum, int pMinLen) {
093: String s = Integer.toString(pNum);
094: for (int i = s.length(); i < pMinLen; i++) {
095: pBuffer.append('0');
096: }
097: pBuffer.append(s);
098: }
099:
100: @Override
101: public StringBuffer format(Object pCalendar, StringBuffer pBuffer,
102: FieldPosition pPos) {
103: if (pCalendar == null) {
104: throw new NullPointerException(
105: "The Calendar argument must not be null.");
106: }
107: if (pBuffer == null) {
108: throw new NullPointerException(
109: "The StringBuffer argument must not be null.");
110: }
111: if (pPos == null) {
112: throw new NullPointerException(
113: "The FieldPosition argument must not be null.");
114: }
115:
116: Calendar cal = (Calendar) pCalendar;
117: if (parseDate) {
118: int year = cal.get(Calendar.YEAR);
119: if (year < 0) {
120: pBuffer.append('-');
121: year = -year;
122: }
123: append(pBuffer, year, 4);
124: pBuffer.append('-');
125: append(pBuffer, cal.get(Calendar.MONTH) + 1, 2);
126: pBuffer.append('-');
127: append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2);
128: if (parseTime) {
129: pBuffer.append('T');
130: }
131: }
132: if (parseTime) {
133: append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2);
134: pBuffer.append(':');
135: append(pBuffer, cal.get(Calendar.MINUTE), 2);
136: pBuffer.append(':');
137: append(pBuffer, cal.get(Calendar.SECOND), 2);
138: int millis = cal.get(Calendar.MILLISECOND);
139: if (millis > 0) {
140: pBuffer.append('.');
141: append(pBuffer, millis, 3);
142: }
143: }
144: TimeZone tz = cal.getTimeZone();
145: // JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis());
146: int offset = cal.get(Calendar.ZONE_OFFSET);
147: if (tz.inDaylightTime(cal.getTime())) {
148: offset += cal.get(Calendar.DST_OFFSET);
149: }
150: if (offset == 0) {
151: pBuffer.append('Z');
152: } else {
153: if (offset < 0) {
154: pBuffer.append('-');
155: offset = -offset;
156: } else {
157: pBuffer.append('+');
158: }
159: int minutes = offset / (60 * 1000);
160: int hours = minutes / 60;
161: minutes -= hours * 60;
162: append(pBuffer, hours, 2);
163: pBuffer.append(':');
164: append(pBuffer, minutes, 2);
165: }
166: return pBuffer;
167: }
168: }
|