blob: 061c14801f79e1408d7f2f6b7b1ee2e9cfb5a392 [file]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.transform.TransformerException;
import org.apache.xml.dtm.XType;
/**
* <meta name="usage" content="general"/>
* This class contains a duration object.
*/
public class DateTimeObj
{
// Datetime formats (era and zone handled separately).
public static final String dt1 = "yyyy-MM-dd'T'HH:mm:ss.ss";
public static final String dt2 = "yyyy-MM-dd'T'HH:mm:ss";
public static final String d = "yyyy-MM-dd";
public static final String gym = "yyyy-MM";
public static final String gy = "yyyy";
public static final String gmd = "MM-dd";
public static final String gm = "MM";
public static final String gd = "dd";
public static final String t1 = "HH:mm:ss.ss";
public static final String t2 = "HH:mm:ss";
private int m_year;
private int m_month;
private int m_day;
private int m_T;
private int m_hour;
private int m_minute;
private double m_second;
private String m_zone;
private Date m_date;
private String m_dateTime;
private int m_size;
private boolean m_signed = false;
/**
* The duration string must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnD, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public DateTimeObj(String dateTimeIn) throws TransformerException
{
this(dateTimeIn, new String[]{dt2});
}
public DateTimeObj(String dateTimeIn, String[] formatsIn) throws TransformerException
{
try {
int i;
m_size = dateTimeIn.length();
// Remember our Time separator
m_T = (i = dateTimeIn.indexOf("T")) != -1 ? i : m_size ;
// boundary check??
String[] edz = getEraDatetimeZone(dateTimeIn);
m_signed = edz[0].length() >0;
m_dateTime = edz[1];
m_zone = edz[2];
if (m_dateTime == null || m_zone == null)
return;
m_date = testFormats(m_dateTime, formatsIn);
int index = dateTimeIn.indexOf('.');
double dec = (index <0) ? 0 :Double.parseDouble(m_dateTime.substring(index));
SimpleDateFormat dateFormat = new SimpleDateFormat(dt1);
dateFormat.setLenient(false);
Calendar cal = Calendar.getInstance();
cal.setTime(m_date);
m_year = cal.get(Calendar.YEAR);
m_month = cal.get(Calendar.MONTH) + 1; // Calendar returns months starting at 0...
m_day = cal.get(Calendar.DATE);
m_hour = cal.get(Calendar.HOUR);
m_minute = cal.get(Calendar.MINUTE);
m_second = (index <0) ? cal.get(Calendar.SECOND)
: cal.get(Calendar.SECOND) + Double.parseDouble(m_dateTime.substring(index));
}
catch (Exception ex)
{
throw new TransformerException(ex);
}
}
public DateTimeObj(Date date, String formatOut) throws TransformerException
{
//m_zone = date.getTimezoneOffset();
SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut);
dateFormat.setLenient(false);
m_dateTime = dateFormat.format(date);
m_date = date;
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(date);
m_signed = (cal.get(Calendar.ERA) == GregorianCalendar.BC);
m_year = cal.get(Calendar.YEAR);
// String monthStr = m_dateTime.substring(5, 7);
// m_month = Integer.valueOf(monthStr).intValue();
// String dayStr = m_dateTime.substring(8, 10);
// m_day = Integer.valueOf(dayStr).intValue();
m_month = cal.get(Calendar.MONTH) + 1;
m_day = cal.get(Calendar.DATE);
m_hour = cal.get(Calendar.HOUR);
m_minute = cal.get(Calendar.MINUTE);
m_second = cal.get(Calendar.SECOND);
// m_year = date.getYear();
// m_month = date.getMonth();
// m_day = date.getDay();
// m_hour = date.getHours();
// m_minute = date.getMinutes();
// m_second = date.getSeconds();
}
/** Added by JJK to support Xerces' stopgap internal representation
* as delivered through DTMSequence. We should work with them to
* converge on a shared time/date/duration object compatable with
* the schema spec.
*
* %BUG% They return some bogus fields due to normalization
* side-effects (they use a pseudodate of 2000/1/15 or something
* like that). To fix that we need to check the schema-type
* and ignore those fields...
*
* %BUG% No idea what format I should be using for m_dateTime!
* */
public DateTimeObj(int[] xercesdate,String typeLocalName)
{
try
{
m_year = Math.abs(xercesdate[0]);
m_month = xercesdate[1];
m_day = xercesdate[2];
m_hour = xercesdate[3];
m_minute = xercesdate[4];
m_second = xercesdate[5]+(xercesdate[6]/1000);
//m_zone = xercesdate[6]; // not sure how encoded
m_signed = (xercesdate[0] < 0);
/* Works, but gives slightly different results. Need to
* investigate...
int type = XType.getTypeFromLocalName(typeLocalName);
String format;
switch (type)
{
case XType.DATE:
format = d;
break;
case XType.TIME:
format = t1;
break;
default:
format = dt1;
}
Calendar cal = Calendar.getInstance();
cal.set(m_year,(m_month-1),m_day,m_hour,m_minute,(int)m_second);
m_date = cal.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false);
m_dateTime = dateFormat.format(m_date);
*/
// Don't particularly like constructing this string,
// but will do for now. Need to investigate why Date or
// Calendar don't work here...
m_dateTime = formatYears(m_year) + "-" + formatDigits(m_month) + "-" + formatDigits(m_day);
// m_dateTime = m_year + "-" + m_month + "-" + m_day;
if (m_hour != 0 && m_minute != 0 && m_second != 0)
m_dateTime = m_dateTime + "T" + formatDigits(m_hour) + ":" + formatDigits(m_minute) + ":" + m_second;
String[] formatsIn = {dt2, d, t2};
m_date = testFormats(m_dateTime, formatsIn);
if (m_signed)
m_dateTime = "-" + m_dateTime;
}
catch (Exception ex)
{
throw new WrappedRuntimeException(ex);
}
// This is wrong but I'm not sure what format I should be using!
//SimpleDateFormat dateFormat = new SimpleDateFormat();
//dateFormat.setLenient(false);
//m_dateTime=dateFormat.format(m_date);
}
/**
* Attempt to parse an input string with the allowed formats, returning
* null if none of the formats work. Input formats are passed in longest to shortest,
* so if any parse operation fails with a parse error in the string, can
* immediately return null.
*/
private static Date testFormats (String in, String[] formats)
throws ParseException
{
for (int i = 0; i <formats.length; i++)
{
try
{
SimpleDateFormat dateFormat = new SimpleDateFormat(formats[i]);
dateFormat.setLenient(false);
return dateFormat.parse(in);
}
catch (ParseException pe)
{
if ( i == formats.length -1)
throw pe;
}
}
return null;
}
/**
* Returns an array with the 3 components that a datetime input string
* may contain: - (for BC era), datetime, and zone. If the zone is not
* valid, return null for that component.
*/
private String[] getEraDatetimeZone(String in) throws TransformerException
{
String leader = "";
String datetime = in;
String zone = "";
if (in.charAt(0)=='-')
{
leader = "-"; // '+' is implicit , not allowed
datetime = in.substring(1);
}
int z = getZoneStart(datetime);
if (z > 0)
{
zone = datetime.substring(z);
datetime = datetime.substring(0, z);
}
else if (z == -2)
zone = null;
//System.out.println("'" + leader + "' " + datetime + " " + zone);
return new String[]{leader, datetime, zone};
}
/**
* Returns an array with the 3 components that a datetime input string
* may contain: - (for BC era), datetime, and zone. If the zone is not
* valid, return null for that component.
*/
private Date normalizeDate(Date date, String zone)
{
if (zone == null || zone.length()==0 || zone.equals("Z") || zone.equals("00:00") )
return date;
else
{
int sign = 1;
if (zone.startsWith("-"))
{
sign = -1;
}
int index = zone.indexOf(":");
int hr = sign * (Integer.parseInt(zone.substring(1, index)));
int min = sign * (Integer.parseInt(zone.substring(index+1)));
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, hr);
cal.add(Calendar.MINUTE, min);
return cal.getTime();
}
}
/**
* Get the start of zone information if the input ends
* with 'Z' or +/-hh:mm. If a zone string is not
* found, return -1; if the zone string is invalid,
* return -2.
*/
private int getZoneStart (String datetime) throws TransformerException
{
if (datetime.indexOf("Z") == datetime.length()-1)
return datetime.indexOf("Z");
else if (
(datetime.lastIndexOf("-") == datetime.length()-6 &&
datetime.charAt(datetime.length()-3) == ':')
||
(datetime.indexOf("+") == datetime.length() -6)
)
{
try
{
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
dateFormat.setLenient(false);
Date d = dateFormat.parse(datetime.substring(datetime.length() -5));
return datetime.length()-6;
}
catch (ParseException pe)
{
throw new TransformerException(pe);
//return -2; // Invalid.
}
}
return -1; // No zone information.
}
/**
* See dateTime.
*/
public static DateTimeObj date() throws TransformerException
{
return currentDateTime(d);
}
/**
* The date:date function returns the date specified in the date/time string given
* as the argument. If no argument is given, then the current local date/time, as
* returned by date:date-time is used as a default argument.
* The date/time string that's returned must be a string in the format defined as the
* lexical representation of xs:dateTime in
* <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* If the argument is not in either of these formats, date:date returns an empty string ('').
* The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
* The date is returned as a string with a lexical representation as defined for xs:date in
* [3.2.9 date] of [XML Schema Part 2: Datatypes]. The date format is basically CCYY-MM-DD,
* although implementers should consult [XML Schema Part 2: Datatypes] and [ISO 8601] for details.
* If no argument is given or the argument date/time specifies a time zone, then the date string
* format must include a time zone, either a Z to indicate Coordinated Universal Time or a + or -
* followed by the difference between the difference from UTC represented as hh:mm. If an argument
* is specified and it does not specify a time zone, then the date string format must not include
* a time zone.
*/
public static DateTimeObj date(String dateIn) throws TransformerException
{
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{d});
return dt;
}
public static DateTimeObj date(Date dateIn) throws TransformerException
{
DateTimeObj dt = new DateTimeObj (dateIn, d);
return dt;
}
/**
* The date:time function returns the time specified in the time string given
* as the argument.
* The time string that's returned must be a string in the format defined as the
* lexical representation of xs:time in
* <a href="http://www.w3.org/TR/xmlschema-2/#time">[3.2.7 time]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* If the argument string is not in this format, date:time returns an empty string ('').
* The time format is basically hh:mm:ss, although implementers should consult
* If no argument is given or the argument time specifies a time zone, then the time string
* format must include a time zone, the difference from UTC represented as hh:mm. If an argument
* is specified and it does not specify a time zone, then the time string format must not include
* a time zone.
*/
public static DateTimeObj time() throws TransformerException
{
return currentDateTime(t1);
}
public static DateTimeObj time(String timeIn) throws TransformerException
{
DateTimeObj dt = new DateTimeObj (timeIn, new String[]{t1, t2});
return dt;
}
public static DateTimeObj time(Date timeIn) throws TransformerException
{
DateTimeObj dt = new DateTimeObj (timeIn, t1);
return dt;
}
public static DateTimeObj gYearMonth(String dateIn) throws TransformerException
{
// Check on java g Date stuff...
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gym});
return dt;
}
public static DateTimeObj gYear(String dateIn) throws TransformerException
{
// Check on java g Date stuff...
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gy});
return dt;
}
public static DateTimeObj gMonth(String dateIn) throws TransformerException
{
// Check on java g Date stuff...
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gm});
return dt;
}
public static DateTimeObj gMonthDay(String dateIn) throws TransformerException
{
// Check on java g Date stuff...
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gmd});
return dt;
}
public static DateTimeObj gDay(String dateIn) throws TransformerException
{
// Check on java g Date stuff...
DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gd});
return dt;
}
/**
* The date:date-time function returns the current date and time as a date/time string.
* The date/time string that's returned must be a string in the format defined as the
* lexical representation of xs:dateTime in
* <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
* The date/time string format must include a time zone, either a Z to indicate Coordinated
* Universal Time or a + or - followed by the difference between the difference from UTC
* represented as hh:mm.
*/
public static DateTimeObj currentDateTime(String pattern) throws TransformerException
{
Calendar cal = Calendar.getInstance();
Date datetime = cal.getTime();
DateTimeObj dt = new DateTimeObj(datetime, pattern);
int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
// If there is no offset, we have "Coordinated
// Universal Time."
if (offset == 0)
dt.setZone("Z");
else
{
// Convert milliseconds to hours and minutes
int hrs = offset/(60*60*1000);
// In a few cases, the time zone may be +/-hh:30.
int min = offset%(60*60*1000);
char posneg = hrs < 0? '-': '+';
dt.setZone(posneg + formatDigits(hrs) + ':' + formatDigits(min));
}
return dt;
}
/**
* See above
*/
public static DateTimeObj dateTime() throws TransformerException
{
return dateTime(dt1);
}
/**
* The date:date-time function returns the date and time specified in the date/time
* string given as the argument..
* The date/time string that's returned must be a string in the format defined as the
* lexical representation of xs:dateTime in
* <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
* The date/time string format must include a time zone, either a Z to indicate Coordinated
* Universal Time or a + or - followed by the difference between the difference from UTC
* represented as hh:mm.
*/
public static DateTimeObj dateTime(String dateTimeIn)
throws TransformerException
{
return new DateTimeObj(dateTimeIn);
}
/**
* Represent the hours and minutes with two-digit strings.
* @param q hrs or minutes.
* @return two-digit String representation of hrs or minutes.
*/
private static String formatDigits(int q)
{
String dd = String.valueOf(Math.abs(q));
return dd.length() == 1 ? "0" + dd : dd;
}
/**
* Represent the hours and minutes with two-digit strings.
* @param q hrs or minutes.
* @return two-digit String representation of hrs or minutes.
*/
private static String formatYears(int q)
{
String dd = String.valueOf(Math.abs(q));
int len = dd.length();
for (int i=len; i<4; i++)
dd = "0" + dd;
return dd;
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMn, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public Duration getYMDuration(DateTimeObj dt) throws TransformerException
{
Duration du = null;
double secs = new Long((m_date.getTime() - dt.m_date.getTime())/1000).doubleValue();
String sign = secs <0 ? "-" : "";
double days = Math.abs(((secs/60)/60)/24);
double months = days/31 + (days%31 <15.5 ? 0 : 1);
int monthDu = new Double(months%12).intValue();
int yearDu = new Double(months/12).intValue();
return new Duration(sign + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "")
+ (monthDu != 0 ? (Integer.toString(monthDu) + "M") : "") );
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMn, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public Duration getDTDuration(DateTimeObj dt) throws TransformerException
{
Duration du = null;
double secs = new Long((m_date.getTime() - dt.m_date.getTime())/1000).doubleValue();
String sign = secs <0 ? "-" : "";
secs = Math.abs(secs);
double secDu = secs%60;
int mins = (new Double(secs)).intValue()/60;
int mnDu = mins%60;
int hours = mins/60;
int hourDu = hours%24;
int dayDu = hours/24;
return new Duration(sign + "P" + (dayDu != 0 ? (Integer.toString(dayDu) + "D") : "")
+ ((hourDu != 0 || mnDu != 0 || secDu != 0) ? "T" : "")
+ (hourDu != 0 ? (Integer.toString(hourDu) + "H") : "")
+ (mnDu != 0 ? (Integer.toString(mnDu) + "M") : "")
+ (secDu != 0 ? (Double.toString(secDu) + "S") : "") );
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnDTnHnMnS, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public boolean lessThan(DateTimeObj dt)
{
if (m_zone.equals(dt.m_zone))
{
if( m_date.before(dt.m_date))
/*
if ((m_year < dt.m_year || (m_year == 0 && dt.m_year == 0)) &&
(m_month < dt.m_month || (m_month == 0 && dt.m_month == 0)) &&
(m_day < dt.m_day || (m_day ==0 && dt.m_day == 0)) &&
(m_hour < dt.m_hour || (m_hour == 0 && dt.m_hour == 0)) &&
(m_minute < m_minute || (m_minute == 0 && m_minute == 0)) &&
(m_second < dt.m_second || (m_second == 0 && dt.m_second == 0)) )
*/
return true;
else
return false;
}
else
{
Date date1 = normalizeDate(m_date, m_zone);
Date date2 = normalizeDate(dt.m_date, dt.m_zone);
if (date1.before(date2))
return true;
else
return false;
}
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnDTnHnMnS, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public boolean lessThanOrEqual(DateTimeObj dt)
{
return (lessThan(dt) || equals(dt));
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnDTnHnMnS, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public boolean greaterThan(DateTimeObj dt)
{
return dt.lessThan(this);
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnDTnHnMnS, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public boolean greaterThanOrEqual(DateTimeObj dt)
{
return (greaterThan(dt) || equals(dt));
}
/**
* The duration function returns the duration specified in the duration
* string given as the argument..
* The duration string that's returned must be a string in the format defined as the
* lexical representation of xs:duration in
* <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>.
* The duration format is basically PnYnMnDTnHnMnS, although implementers should consult
* <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and
* <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details.
*/
public boolean equals(DateTimeObj dt)
{
if (m_zone.equals(dt.m_zone))
{
if (m_year == dt.m_year &&
m_month == dt.m_month &&
m_day == dt.m_day &&
m_hour == dt.m_hour &&
m_minute == dt.m_minute &&
m_second == dt.m_second)
return true;
else
return false;
}
else
{
Date date1 = normalizeDate(m_date, m_zone);
Date date2 = normalizeDate(dt.m_date, dt.m_zone);
if (date1.before(date2) || date2.before(date1))
return false;
else
return true;
}
}
public DateTimeObj addDays(double days)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
cal.add(Calendar.DATE, new Double(days).intValue());
DateTimeObj dateTime = date(cal.getTime());
dateTime.setZone(m_zone);
return dateTime;
}
public DateTimeObj addYMDurationToDateTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? -1 : 1;
cal.add(Calendar.YEAR, sign * (d.getYears()));
cal.add(Calendar.MONTH, sign * (d.getMonths()));
DateTimeObj dateTime = new DateTimeObj(cal.getTime(), dt2 );
dateTime.setZone(m_zone);
return dateTime;
}
public DateTimeObj addYMDurationToDate(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? -1 : 1;
cal.add(Calendar.YEAR, sign * (d.getYears()));
cal.add(Calendar.MONTH, sign * (d.getMonths()));
DateTimeObj dt = date(cal.getTime());
dt.setZone(m_zone);
return dt;
}
public DateTimeObj subtractYMDurationFromDateTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? 1 : -1;
cal.add(Calendar.MONTH, sign * (d.getMonths() + (d.getYears() * 12)));
DateTimeObj dateTime = new DateTimeObj(cal.getTime(), dt1);
dateTime.setZone(m_zone);
return dateTime;
}
public DateTimeObj subtractYMDurationFromDate(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? 1 : -1;
cal.add(Calendar.MONTH, sign * (d.getMonths() + (d.getYears() * 12)));
DateTimeObj dt = date(cal.getTime());
dt.setZone(m_zone);
return dt;
}
public DateTimeObj addDTDurationToDateTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? -1 : 1;
double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60);
int intVal = new Double(secs).intValue();
cal.add(Calendar.SECOND , sign * intVal);
Date date = cal.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat(dt2);
dateFormat.setLenient(false);
String dateTime = dateFormat.format(date);
if (secs - intVal != 0)
{
String val = Double.toString(secs);
int index = val.indexOf('.');
dateTime = (index<0) ? dateTime : dateTime + val.substring(index);
}
//DateTimeObj dt = new DateTimeObj(cal.getTime(), dt2);
DateTimeObj dt = new DateTimeObj(dateTime);
dt.setZone(m_zone);
return dt;
}
public DateTimeObj addDTDurationToDate(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? -1 : 1;
cal.add(Calendar.MONTH, sign * (d.getMonths()));
cal.add(Calendar.DATE, sign * (d.getDays()));
DateTimeObj dt = date(cal.getTime());
dt.setZone(m_zone);
return dt;
}
public DateTimeObj addDTDurationToTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? -1 : 1;
double secs = d.getSeconds() + ((((d.getHours()) * 60) + d.getMinutes()) * 60);
int intVal = new Double(secs).intValue();
cal.add(Calendar.SECOND , sign * intVal);
Date date = cal.getTime();
SimpleDateFormat dateFormat = new SimpleDateFormat(t2);
dateFormat.setLenient(false);
String dateTime = dateFormat.format(date);
if (secs - intVal != 0)
{
String val = Double.toString(secs);
int index = val.indexOf('.');
dateTime = (index<0) ? dateTime : dateTime + val.substring(index);
}
DateTimeObj dt = time(dateTime);
dt.setZone(m_zone);
return dt;
}
public DateTimeObj subtractDTDurationFromDateTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? 1 : -1;
double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60);
cal.add(Calendar.SECOND , sign * (new Double (Math.floor(secs)).intValue()));
DateTimeObj dt = new DateTimeObj(cal.getTime(), dt1);
dt.setZone(m_zone);
return dt;
}
public DateTimeObj subtractDTDurationFromDate(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? 1 : -1;
// subtracting 1 from the number of days, because counting
// from end of given day, so it counts for day 1
// cal.add(Calendar.DATE, sign * (d.getDays()-1));
// "(date('2002-08-05')-duration('P42D'))+duration('P42D') = date('2002-08-05')"
// doesn't work if you do the -1. It sure feels like that is wrong.
// -sb
double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60);
cal.add(Calendar.SECOND , sign * (new Double (Math.floor(secs)).intValue()));
DateTimeObj dt = date(cal.getTime());
dt.setZone(m_zone);
return dt;
}
/**
* Method subtractDateFromDate.
* @param date2
* @return Duration
* @throws TransformerException
*/
public Duration subtractDateFromDate(DateTimeObj date2)
throws TransformerException
{
/*Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int year = m_year - date2.m_year;
int month = m_month - date2.m_month;
int day = m_day - date2.m_day;
int hour = m_hour - date2.m_hour;
int minute = m_minute - date2.m_minute;
double second = m_second - date2.m_second;
Duration dur = new Duration(year, month, day, hour, minute, second);
return dur;*/
return getDTDuration(date2);
}
public DateTimeObj subtractDTDurationFromTime(Duration d)
throws TransformerException
{
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(m_date);
int sign = (d.getSigned()) ? 1 : -1;
double secs = d.getSeconds() + ((((d.getHours()) * 60) + d.getMinutes()) * 60);
cal.add(Calendar.SECOND , sign * (new Double(Math.floor(secs)).intValue()));
DateTimeObj dt = time(cal.getTime());
dt.setZone(m_zone);
return dt;
}
public void setYears(int years)
{
m_year = years;
}
public int getYears()
{
return m_year;
}
public void setMonths(int months)
{
m_month = months;
}
public int getMonths()
{
return m_month;
}
public void setDays(int days)
{
m_day = days;
}
public int getDays()
{
return m_day;
}
public void setHours(int hours)
{
m_hour = hours;
}
public int getHours()
{
return m_hour;
}
public void setSeconds(double secs)
{
m_second = secs;
}
public double getSeconds()
{
return m_second;
}
public void setMinutes(int mts)
{
m_minute = mts;
}
public int getMinutes()
{
return m_minute;
}
public void setZone(String zone)
{
m_zone = zone;
}
public String getZone()
{
if (m_zone.equals("Z") )
return ("00:00");
else
return m_zone;
}
public Date getDate()
{
return m_date;
}
public String toString()
{
return (m_dateTime + (m_zone == null ? "" : m_zone));
}
}