org.exolab.castor.types.DateTime Maven / Gradle / Ivy
Show all versions of castor-xml Show documentation
/*
* Copyright 2006 Edward Kuns
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
* $Id: $
*/
package org.exolab.castor.types;
import java.text.ParseException;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* Describe an XML schema DateTime.
*
* The format is defined by W3C XML Schema Recommendation and ISO8601 i.e
* (-)CCYY-MM-DD'T'HH:MM:SS(.SSSSS)(Z|(+|-)hh:mm)
*
* @author Edward Kuns
* @version $Revision: 0000 $
*/
public class DateTime extends DateTimeBase {
/** SerialVersionUID. */
private static final long serialVersionUID = 6278590966410879734L;
/** Complaint string. */
private static final String BAD_DATE = "Bad DateTime format: ";
/**
* Default constructor.
*/
public DateTime() {
// Nothing for the default
}
/**
* Constructs a XML Schema DateTime instance given all the values of the different date and time
* (but not time zone) fields.
*
* By default a DateTime is not UTC, and is local. To set a timezone, you need to separately call
* {@link #setZone(short, short)}.
*
* @param values an array of shorts that represent the different fields of Time.
* @see #setValues
*/
public DateTime(short[] values) {
setValues(values);
}
/**
* Creates a new XML Schema DateTime instance from a long that represents a Date. No time zone
* information is set.
*
* By default a DateTime is not UTC, and is local. To set a timezone, you need to separately call
* {@link #setZone(short, short)}.
*
* @param dateAsLong java.util.Date represented as a long.
*/
public DateTime(long dateAsLong) {
this(new java.util.Date(dateAsLong));
}
/**
* Creates a new XML Schema DateTime instance from a java.util.Date. No time zone information is
* set.
*
* By default a DateTime is not UTC, and is local. To set a timezone, you need to separately call
* {@link #setZone(short, short)}.
*
* @param dateRef a java.util.Date to convert.
*/
public DateTime(java.util.Date dateRef) {
GregorianCalendar tempCalendar = new GregorianCalendar();
tempCalendar.setTime(dateRef);
setCentury((short) (tempCalendar.get(Calendar.YEAR) / 100));
setYear((short) (tempCalendar.get(Calendar.YEAR) % 100));
// In GregorianCalendar, 0 <= Month <= 11; January == 0
setMonth((short) (tempCalendar.get(Calendar.MONTH) + 1));
setDay((short) tempCalendar.get(Calendar.DAY_OF_MONTH));
setHour((short) tempCalendar.get(Calendar.HOUR_OF_DAY));
setMinute((short) tempCalendar.get(Calendar.MINUTE));
setSecond((short) tempCalendar.get(Calendar.SECOND),
(short) tempCalendar.get(Calendar.MILLISECOND));
}
/**
* Constructs a DateTime from a String. The String is expected to be in W3C Schema DateTime
* format.
*
* @param date the string representing the date
* @throws java.text.ParseException if we are passed an illegal value
*/
public DateTime(String date) throws java.text.ParseException {
parseDateTimeInternal(date, this);
}
/**
* Sets all the fields to the values provided in an Array. The Array must be at least eight
* entries long. Extra entries are ignored. The order of entries in the array is as follows:
*
* - century
* - year
* - month
* - day
* - hour
* - minute
* - second
* - millisecond
*
* If a Time Zone is to be specified, it has to be set separately by using
* {@link DateTimeBase#setZone(short, short) setZone}. A time zone previously set will not be
* cleared.
*
* @param values An array of shorts containing the values for the DateTime
*/
public void setValues(short[] values) {
if (values.length != 8) {
throw new IllegalArgumentException(
"DateTime#setValues: Array length " + values.length + " != 8");
}
this.setCentury(values[0]);
this.setYear(values[1]);
this.setMonth(values[2]);
this.setDay(values[3]);
this.setHour(values[4]);
this.setMinute(values[5]);
this.setSecond(values[6], values[7]);
}
/**
* Returns an array of shorts with all the fields that describe this DateTime type. The order of
* entries in the array is as follows:
*
* - century
* - year
* - month
* - day
* - hour
* - minute
* - second
* - millisecond
*
* Note:the time zone is not included.
*
* @return an array of short with all the fields that describe this Date type.
*/
public short[] getValues() {
short[] result = new short[8];
result[0] = this.getCentury();
result[1] = this.getYear();
result[2] = this.getMonth();
result[3] = this.getDay();
result[4] = this.getHour();
result[5] = this.getMinute();
result[6] = this.getSeconds();
result[7] = this.getMilli();
return result;
} // getValues
/**
* Converts this DateTime into a local java.util.Date.
*
* @return a local java.util.Date representing this DateTime.
*/
public java.util.Date toDate() {
Calendar calendar = new GregorianCalendar(getCentury() * 100 + getYear(), getMonth() - 1,
getDay(), getHour(), getMinute(), getSeconds());
calendar.set(Calendar.MILLISECOND, getMilli());
setDateFormatTimeZone(calendar);
return calendar.getTime();
} // toDate()
/**
* Converts this DateTime into a long value representing a java.util.Date.
*
* @return This DateTime instance as a long value representing a java.util.Date.
*/
public long toLong() {
return toDate().getTime();
}
/**
* Converts this DateTime to a string. The format is defined by W3C XML Schema recommendation and
* ISO8601: (+|-)CCYY-MM-DDTHH:MM:SS.SSS(+/-)HH:SS
*
* @return a string representing this Date
*/
public String toString() {
StringBuffer result = new StringBuffer();
appendDateString(result);
result.append('T');
appendTimeString(result);
appendTimeZoneString(result);
return result.toString();
} // toString
/**
* Parses a String into a new DateTime instance.
*
* @param str the string to parse
* @return a new DateTime instance with the value of the parsed string.
* @throws ParseException If the string to parse does not follow the right format
*/
public static DateTime parse(String str) throws ParseException {
return parseDateTime(str);
}
/**
* Parses a String into a new DateTime instance.
*
* @param str the string to parse
* @return a new DateTime instance with the value of the parsed string.
* @throws ParseException If the string to parse does not follow the right format
*/
public static DateTime parseDateTime(String str) throws ParseException {
return parseDateTimeInternal(str, new DateTime());
}
/**
* Parses a String into the provided DateTime instance (or a new DateTime instance if the one
* provided is null) and assigns that value to the DateTime instance given.
*
* @param str the string to parse
* @param result the DateTime instance to assign to the parsed value of the String. If null is
* passed, a new DateTime instance is created to be returned.
* @return the DateTime instance with the value of the parsed string.
* @throws ParseException If the string to parse does not follow the right format
*/
private static DateTime parseDateTimeInternal(String str, DateTime result) throws ParseException {
if (str == null) {
throw new IllegalArgumentException("The string to be parsed must not be null.");
}
if (result == null) {
result = new DateTime();
}
char[] chars = str.toCharArray();
if (chars.length < 19) {
throw new ParseException(BAD_DATE + str + "\nDateTime is not long enough", 0);
}
int idx = 0;
idx = parseYear(str, result, chars, idx, BAD_DATE);
idx = parseMonth(str, result, chars, idx, BAD_DATE);
idx = parseDay(str, result, chars, idx, BAD_DATE);
if (chars[idx] != 'T') {
throw new ParseException(BAD_DATE + str + "\n 'T' " + DateTimeBase.WRONGLY_PLACED, idx);
}
idx++;
idx = parseTime(str, result, chars, idx, BAD_DATE);
parseTimeZone(str, result, chars, idx, BAD_DATE);
return result;
} // parse
}