blob: 23ef80c41aea9c2aebaca25d0cece29e3769afbe [file] [log] [blame]
/*
* 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.util.Date;
import java.util.TimeZone;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
import javax.xml.transform.TransformerException;
import org.apache.xpath.objects.XString;
import org.apache.xpath.objects.XDouble;
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XObject;
/**
* <meta name="usage" content="general"/>
* This class contains a duration object.
*/
public class Duration
{
// Duration format
public static final String du = "PnYnMnDTnHnMn.nS";
private int m_year;
private int m_month;
private int m_day;
private static int m_T;
private int m_hour;
private int m_minute;
private double m_second;
private boolean m_signed;
private String m_sign = "-";
private String m_duration;
private int m_size;
/**
* 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 Duration(String duration) throws TransformerException
{
m_duration = duration;
int i;
m_size = duration.length();
m_signed = duration.startsWith("-");
int offset;
int start = offset = (m_signed ? 2 : 1); // Bypass the P
// Remember our Time separator
m_T = (i = duration.indexOf("T")) != -1 ? i : m_size ;
// boundary check??
// Maybe I can avoid doing string operations here if I will not need
// the individual values?? ie: int nY = ( (i = duration.indexOf("Y")) != -1) ? i - start : 0;
String nY = ( (i = duration.indexOf("Y")) != -1) ? duration.substring(start, i) :"";
start = (i > 0) ? (i + 1) : start ;
String nM = ((i = duration.substring(0,m_T).indexOf("M")) != -1 ) ? duration.substring(start, i) :"";
start = (i > 0) ? (i + 1) : start ;
String nD = ( (i = duration.indexOf("D")) != -1) ? duration.substring(start, i) :"";
try{
m_year = nY.length() >0 ? Integer.parseInt(nY) :0;
m_month = nM.length() >0 ? Integer.parseInt(nM) :0;
m_day = nD.length() >0 ? Integer.parseInt(nD) :0;
if (m_T < m_size)
{
start = (m_T < m_size) ? m_T + 1 : start;
String nH = ( (i = duration.indexOf("H")) != -1) ? duration.substring(start, i) :"";
start = (i > 0) ? (i + 1) : start ;
String nMt = ( (i = duration.substring(m_T, m_size).indexOf("M")) != -1) ? duration.substring(start, i+=m_T) :"";
start = (i > 0) ? (i + 1) : start ;
String nS = ( (i = duration.indexOf("S")) != -1) ? duration.substring(start, i) :"";
m_hour = nH.length() >0 ? Integer.parseInt(nH) :0;
m_minute = nMt.length() >0 ? Integer.parseInt(nMt) :0;
m_second = nS.length() >0 ? Double.valueOf(nS).doubleValue() :0;
}
}
catch (NumberFormatException nfe)
{
throw new TransformerException(nfe);
}
}
/** 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.
* */
public Duration(int[] xercesduration)
{
// I'm not sure how they're representing negative durations!?
m_year = xercesduration[0];
m_month = xercesduration[1];
m_day = xercesduration[2];
m_hour = xercesduration[3];
m_minute = xercesduration[4];
m_second = xercesduration[5]+(xercesduration[6]/1000);
// xercesduration[8] is timezone related; ignore it.
}
public Duration(int year, int month, int day, int hour, int minute, double second)
{
// I'm not sure how they're representing negative durations!?
m_year = year;
m_month = month;
m_day = day;
m_hour = hour;
m_minute = minute;
m_second = second;
if(year < 0)
m_signed = true;
// xercesduration[8] is timezone related; ignore it.
}
/**
* 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 static Duration duration(Duration du)
{
//Duration du = new Duration (duration);
int len = du.m_size;
if (!du.m_duration.startsWith("P", (du.m_signed ? 1 : 0)) ||
(du.m_year == 0 && du.m_month == 0 && du.m_day == 0 && du.m_hour == 0 && du.m_minute == 0 && du.m_second == 0) ||
(m_T == len && (du.m_hour != 0 || du.m_minute != 0 || du.m_second != 0)) ||
m_T == len -1)
return null;
return du;
}
/**
* 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 static Duration YMDuration(String duration) throws TransformerException
{
Duration du = duration(new Duration (duration));
if (du == null)
return null;
if (!duration.startsWith("P", (du.m_signed ? 1 : 0)) ||
(du.m_day != 0 || du.m_hour != 0 || du.m_minute != 0 || du.m_second != 0) ||
(du.m_year == 0 && du.m_month == 0) )
return null;
return du;
}
/**
* 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 static Duration YMDurationFromMonths(int months) throws TransformerException
{
String sign = (months > 0) ? "" : "-";
months = Math.abs(months);
int monthDu = months%12;
int yearDu = months/12;
return new Duration ( sign + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : ""));
}
public static Duration DTDuration(String duration) throws TransformerException
{
Duration du = duration(new Duration (duration));
if (!duration.startsWith("P", (du.m_signed ? 1 : 0)) ||
(du.m_year != 0 || du.m_month != 0) ||
(du.m_day == 0 && du.m_hour == 0 && du.m_minute == 0 && du.m_second == 0) )
return null;
return du;
}
/**
* 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 static Duration DTDurationFromSecs(double secs) throws TransformerException
{
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 DTEqual(Duration du)
{
if ((m_signed == du.m_signed) &&
m_day == du.m_day &&
m_hour == du.m_hour &&
m_minute == du.m_minute &&
m_second == du.m_second)
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 DTLessThan(Duration du)
{
int sign = (m_signed) ? -1 : 1;
int hrs = m_hour + (m_day * 24);
int mns = m_minute + (hrs * 60);
double secs = (m_second + (mns * 60)) * sign;
sign = (du.m_signed) ? -1 : 1;
hrs = du.m_hour + (du.m_day * 24);
mns = du.m_minute + (hrs * 60);
double secs2 = (du.m_second + (mns * 60)) * sign;
if (secs < secs2)
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 DTLessThanOrEqual(Duration du)
{
return (DTLessThan(du) || DTEqual(du));
}
/**
* 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 DTGreaterThan(Duration du)
{
return du.DTLessThan(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 DTGreaterThanOrEqual(Duration du)
{
return (DTGreaterThan(du) || DTEqual(du));
}
/**
* 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 YMEqual(Duration du)
{
if ((m_signed == du.m_signed) &&
m_year == du.m_year &&
m_month == du.m_month)
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 YMLessThan(Duration du)
{
int sign = (m_signed) ? -1 : 1;
int months = (m_month + (m_year * 12)) * sign;
sign = (du.m_signed) ? -1 : 1;
int months2 = (du.m_month + (du.m_year * 12)) * sign;
if (months < months2)
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 YMLessThanOrEqual(Duration du)
{
return (YMLessThan(du) || YMEqual(du));
}
/**
* 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 YMGreaterThan(Duration du)
{
return du.YMLessThan(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 YMGreaterThanOrEqual(Duration du)
{
return (YMGreaterThan(du) || YMEqual(du));
}
/**
* 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(Duration du)
{
if ((m_signed == du.m_signed) &&
m_year == du.m_year &&
m_month == du.m_month &&
m_day == du.m_day &&
m_hour == du.m_hour &&
m_minute == du.m_minute &&
m_second == du.m_second)
return true;
else
return false;
}
public Duration addYMDuration(Duration d)
throws TransformerException
{
String sign;
int monthDu, yearDu;
if (m_signed == d.m_signed) //!signed1 && !signed1 || signed1 && signed2)
{
sign = (m_signed) ? m_sign : "";
int months = m_month + d.m_month;
monthDu = months%12;
yearDu = months/12 + m_year + d.m_year;
}
else
{
int y1 = m_year;
int y2 = d.m_year;
int y = (m_signed) ? y2 - y1 : y1 - y2;
int m1 = m_month;
int m2 = d.m_month;
int months = (m_signed) ? m2 - m1 + (y*12) : m1 - m2 + (y*12);
sign = months > 0 ? "" : "-";
months = Math.abs(months);
monthDu = months%12;
yearDu = months/12;
}
return new Duration(sign + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : ""));
}
public Duration subtractYMDuration(Duration d)
throws TransformerException
{
String sign;
int monthDu, yearDu;
if (m_signed == d.m_signed)
{
int y1 = m_year;
int y2 = d.m_year;
int y = (m_signed) ? y2 - y1 : y1 - y2;
int m1 = m_month;
int m2 = d.m_month;
int months = (m_signed) ? m2 - m1 + (y*12) : m1 - m2 + (y*12);
sign = months > 0 ? "" : m_sign;
months = Math.abs(months);
monthDu = months%12;
yearDu = months/12;
}
else
{
sign = (m_signed) ? m_sign : "";
int months = m_month + d.m_month;
monthDu = months%12;
yearDu = months/12 + m_year + d.m_year;
}
return new Duration(sign + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : ""));
}
public Duration multiplyYMDuration(double dec)
throws TransformerException
{
int sign = (m_signed) ? -1 : 1;
double months = (m_month + (m_year * 12)) * dec * sign;
months = Math.floor(months + .5);
//months = (new Double(Math.floor(new Integer(months).doubleValue()))).intValue()
double ms = Math.abs(months);
int monthDu = (new Double(ms%12)).intValue();
int yearDu = (new Double(ms/12)).intValue();
//new Double(Math.floor(new Integer(months/12).doubleValue())).intValue();
return new Duration((months > 0 ? "" : m_sign) + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : ""));
}
public Duration divideYMDuration(double dec)
throws TransformerException
{int sign = (m_signed) ? -1 : 1;
double months = (m_month + (m_year * 12)) / dec * sign;
months = Math.floor(months + .5);
double ms = Math.abs(months);
int monthDu = (new Double(ms%12)).intValue();
int yearDu = (new Double(ms/12)).intValue();
//new Double(Math.floor(new Integer(months/12).doubleValue())).intValue();
return new Duration((months > 0 ? "" : m_sign) + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : ""));
}
public Duration addDTDuration(Duration du)
throws TransformerException
{
String sign;
int dayDu, hourDu, mnDu;
double secDu;
if (m_signed == du.m_signed) //!signed1 && !signed1 || signed1 && signed2)
{
sign = (m_signed) ? m_sign : "";
double secs = m_second + du.m_second;
secDu = secs%60;
int mins = (new Double(secs)).intValue()/60 + m_minute + du.m_minute;
mnDu = mins%60;
int hours = mins/60 + m_hour + du.m_hour;
hourDu = hours%24;
dayDu = hours/24 + m_day + du.m_day;
}
else
{
int d1 = m_day;
int d2 = du.m_day;
int d = (m_signed) ? d2 - d1 : d1 - d2;
int h1 = m_hour;
int h2 = du.m_hour;
int h = (m_signed) ? h2 - h1 + (d*24) : h1 - h2 + (d*24);
int m1 = m_minute;
int m2 = du.m_minute;
int m = (m_signed) ? m2 - m1 + (h*60) : m1 - m2 + (h*60);
double s1 = m_second;
double s2 = du.m_second;
double s = (m_signed) ? s2 - s1 + (m*60) : s1 - s2 + (m*60);
sign = s > 0 ? "" : m_sign;
s = Math.abs(s);
secDu = s%60;
m = (new Double(s)).intValue()/60;
mnDu = m%60;
h = m/60;
hourDu = h%24;
dayDu = h/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") : "") );
}
public Duration subtractDTDuration(Duration du)
throws TransformerException
{
String sign;
int dayDu, hourDu, mnDu;
double secDu;
if (m_signed == du.m_signed)
{
int d1 = m_day;
int d2 = du.m_day;
int d = (m_signed) ? d2 - d1 : d1 - d2;
int h1 = m_hour;
int h2 = du.m_hour;
int h = (m_signed) ? h2 - h1 + (d*24) : h1 - h2 + (d*24);
int m1 = m_minute;
int m2 = du.m_minute;
int m = (m_signed) ? m2 - m1 + (h*60) : m1 - m2 + (h*60);
double s1 = m_second;
double s2 = du.m_second;
double s = (m_signed) ? s2 - s1 + (m*60) : s1 - s2 + (m*60);
sign = s > 0 ? "" : m_sign;
s = Math.abs(s);
secDu = s%60;
m = (new Double(s)).intValue()/60;
mnDu = m%60;
h = m/60;
hourDu = h%24;
dayDu = h/24;
}
else
{
sign = (m_signed) ? m_sign : "";
double secs = m_second + du.m_second;
secDu = secs%60;
int mins = (new Double(secs)).intValue()/60 + m_minute + du.m_minute;
mnDu = mins%60;
int hours = mins/60 + m_hour + du.m_hour;
hourDu = hours%24;
dayDu = hours/24 + m_day + du.m_day;
}
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") : "") );
}
public Duration multiplyDTDuration(double dec)
throws TransformerException
{
int sign = (m_signed) ? -1 : 1;
int hrs = m_hour + (m_day * 24);
int mns = m_minute + (hrs * 60);
double secs = (m_second + (mns * 60)) * dec * sign;
double s = Math.abs(secs);
double secDu = s%60;
mns = (new Double(s/60)).intValue();
int mnDu = mns%60;
hrs = mns/60;
int hrDu = hrs%24;
int dayDu = hrs/24;
return new Duration((secs > 0 ? "" : m_sign) + "P" + (dayDu != 0 ? (Integer.toString(dayDu) + "D") : "")
+ ((hrDu != 0 || mnDu != 0 || secDu != 0) ? "T" : "")
+ (hrDu != 0 ? (Integer.toString(hrDu) + "H") : "")
+ (mnDu != 0 ? (Integer.toString(mnDu) + "M") : "")
+ (secDu != 0 ? (Double.toString(secDu) + "S") : ""));
}
public Duration divideDTDuration(double dec)
throws TransformerException
{
int sign = (m_signed) ? -1 : 1;
int hrs = m_hour + (m_day * 24);
int mns = m_minute + (hrs * 60);
double secs = Math.floor(((m_second + (mns * 60)) / dec) + .5) * sign;
secs = Math.floor(secs);
double s = Math.abs(secs);
double secDu = s%60;
mns = (new Double(s/60)).intValue();
int mnDu = mns%60;
hrs = mns/60;
int hrDu = hrs%24;
int dayDu = hrs/24;
return new Duration((secs > 0 ? "" : m_sign) + "P" + (dayDu != 0 ? (Integer.toString(dayDu) + "D") : "")
+ ((hrDu != 0 || mnDu != 0 || secDu != 0) ? "T" : "")
+ (hrDu != 0 ? (Integer.toString(hrDu) + "H") : "")
+ (mnDu != 0 ? (Integer.toString(mnDu) + "M") : "")
+ (secDu != 0 ? (Double.toString(secDu) + "S") : ""));
}
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 boolean getSigned()
{
return m_signed;
}
public String toString()
{
if (null == m_duration)
{
m_duration =
(m_signed ? m_sign : "")
+ "P"
+ ((m_year > 0) ? m_year + "Y" : "")
+ ((m_month > 0) ? m_month + "M" : "")
+ ((m_day > 0) ? m_day +"D": "")
+ ((m_hour != 0 || m_minute != 0 || m_second != 0) ? "T" : "")
+ ((m_hour != 0) ? m_hour + "H" : "")
+ ((m_minute != 0) ? m_minute + "M" : "")
+ ((m_second != 0) ? m_second + "S" : "");
}
return m_duration;
// return m_duration;
}
}