/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
o 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.
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
*/
package Framework;
import java.beans.PropertyChangeEvent;
import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
/**
* Class for describing intervals of time
* <P>
* Implementation allows operations on time intervals
*<P>
*
*/
public class IntervalData extends DataValue implements Serializable
{
private static final long msPER_DAY = 1000 * 60 * 60 * 24;
private static final long msPER_HOUR = 1000 * 60 * 60;
private static final long msPER_MIN = 1000 * 60;
private static final long msPER_SEC = 1000;
private static Logger _log = Logger.getLogger(IntervalData.class);
/**
* Resolves ambiguous constructor arguments
*/
public static class qq_Resolver {
public static final int cISNULL = 1;
public static final int cVALUE = 2;
public static final int cTEXTVALUE = 3;
public static final int cISNULL_TEXTVALUE = 4;
public static final int cISNULL_VALUE = 5;
}
public IntervalData(IntervalData value) {
super();
this.day = value.day;
this.hour = value.hour;
this.min = value.min;
this.month = value.month;
this.msec = value.msec;
this.sec = value.sec;
this.year = value.year;
}
public IntervalData(boolean pIsNull, int pResolver) {
super();
// this.setIsNull( pIsNull);
}
public IntervalData(TextData pValue) {
super();
this.setValue(pValue);
}
public IntervalData(String pValue) {
super();
this.setValue(pValue);
}
public IntervalData(TextData pValue, int pResolver) {
super();
if (pResolver == IntervalData.qq_Resolver.cTEXTVALUE)
this.setValue(pValue);
else if (pResolver == IntervalData.qq_Resolver.cVALUE)
this.setValue(pValue);
}
public IntervalData(String pValue, int pResolver) {
super();
if (pResolver == IntervalData.qq_Resolver.cTEXTVALUE)
this.setValue(pValue);
else if (pResolver == IntervalData.qq_Resolver.cVALUE)
this.setValue(pValue);
}
public IntervalData(boolean pBool, TextData pValue, int pResolver) {
super();
if (pResolver == IntervalData.qq_Resolver.cISNULL_TEXTVALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
}
else if (pResolver == IntervalData.qq_Resolver.cISNULL_VALUE) {
this.setValue( pValue );
// this.isNull = pBool1;
}
}
public IntervalData(boolean pBool, String pValue, int pResolver) {
super();
if (pResolver == IntervalData.qq_Resolver.cISNULL_TEXTVALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
}
else if (pResolver == IntervalData.qq_Resolver.cISNULL_VALUE) {
this.setValue( pValue );
// this.isNull = pBool1;
}
}
public static final short version = 1;
/**
* years
*/
public int year;
/**
* months
*/
public int month;
/**
* days
*/
public int day;
/**
* hours
*/
public int hour;
/**
* minutes
*/
public int min;
/**
* seconds
*/
public int sec;
/**
* milliseconds
*/
public long msec;
/**
* Default constructor
*/
public IntervalData()
{
super();
}
public IntervalData(int msecs){
this();
setValue(msecs);
}
public IntervalData
(
int _year, int _month, int _day, int _hour, int _min, int _sec, int _msec
)
{
super();
year = _year;
month = _month;
day = _day;
hour = _hour;
min = _min;
sec = _sec;
msec = _msec;
}
public int getUnit(int resolution)
{
switch (resolution)
{
case 1:
return this.year;
case 3:
return this.month;
case 4:
return this.day;
case 5:
return this.hour;
case 6:
return this.min;
case 7:
return this.sec;
case 8:
return (int)this.msec;
default:
return 0;
}
}
public void setUnit(int resolution, int value)
{
switch (resolution)
{
case 1:
this.year = value;
break;
case 3:
this.month = value;
break;
case 4:
this.day = value;
break;
case 5:
this.hour = value;
break;
case 6:
this.min = value;
break;
case 7:
this.sec = value;
break;
case 8:
this.msec = value;
break;
default:
break;
}
super.reportChange();
}
public IntervalData setUnit(int pYear, int pMonth, int pDay, int pHour, int pMinute, int pSecond, int pMillisecond)
{
this.year = pYear;
this.month = pMonth;
this.day = pDay;
this.hour = pHour;
this.min = pMinute;
this.sec = pSecond;
this.msec = pMillisecond;
super.reportChange();
return this;
}
public IntervalData addUnit(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
this.year += years;
this.month += months;
this.day += days;
this.hour += hours;
this.min += minutes;
this.sec += seconds;
this.msec += milliseconds;
super.reportChange();
return this;
}
public IntervalData addUnit(int years)
{
this.year += years;
return this;
}
public boolean asBoolean()
{
return(false);
}
public double asDouble()
{
// TF:12/05/2010:Testing shows that this throws an exception
// return this.convertToUnitLong(Constants.DR_SECOND);
data_RaiseInvalidConversionExcpt(this, "<DOUBLE>");
return 0.0;
}
public float asFloat()
{
// TF:12/05/2010:Testing shows that this throws an exception
// return this.convertToUnitLong(Constants.DR_SECOND);
data_RaiseInvalidConversionExcpt(this, "<DOUBLE>");
return 0.0f;
}
public long asLong()
{
// TF:12/05/2010:Testing shows that this throws an exception
// return this.convertToUnitLong(Constants.DR_SECOND);
data_RaiseInvalidConversionExcpt(this, "<DOUBLE>");
return 0;
}
public String toString()
{
return(new Integer(year).toString() + ":" + new Integer(month).toString() + ":" + new Integer(day).toString() + ":" + new Integer(hour).toString() + ":" + new Integer(min).toString() + ":" + new Integer(sec).toString() + ":" + msec);
}
public TextData asTextData()
{
return(new TextData(this.toString()));
}
public void setValue(DataValue dvalue)
{
// TF:22/02/2009:Changed this to handle null properly
if(dvalue == null) {
data_RaiseInvalidMethodExcpt();
}
if(!(dvalue instanceof IntervalData)) {
UsageException errorVar = new UsageException();
ErrorMgr.addError(errorVar);
throw errorVar;
}
if (dvalue.checkNullValue()) {
setNull();
}
else {
IntervalData id = (IntervalData)(dvalue);
this.year = id.year;
this.month = id.month;
this.day = id.day;
this.hour = id.hour;
this.min = id.min;
this.sec = id.sec;
this.msec = id.msec;
}
}
public void setValue(TextData tvalue)
{
if(tvalue == null) {
NullPointerException errorVar = new NullPointerException();
ErrorMgr.addError(errorVar);
throw errorVar;
}
setValue(tvalue.toString());
}
public void setValue(String svalue)
{
if(svalue == null) {
NullPointerException errorVar = new NullPointerException();
ErrorMgr.addError(errorVar);
throw errorVar;
}
this.day = 0;
this.hour = 0;
this.min = 0;
this.month = 0;
this.msec = 0;
this.sec = 0;
this.year = 0;
StringTokenizer st = new StringTokenizer(svalue, ":");
for (int j = 0; st.hasMoreTokens(); j++) {
String s = st.nextToken();
Integer i = new Integer(s);
switch (j) {
case 0:
this.year = i.intValue();
break;
case 1:
this.month = i.intValue();
break;
case 2:
this.day = i.intValue();
break;
case 3:
this.hour = i.intValue();
break;
case 4:
this.min = i.intValue();
break;
case 5:
this.sec = i.intValue();
break;
case 6:
this.msec = i.intValue();
break;
}
}
super.reportChange();
}
/**
* Set the value of the interval data based on val. CraigM:26/06/2008.
* @param milliseconds time in milliseconds
*/
public void setValue(long milliseconds) {
// CraigM:26/06/2008 - The use of GregorianCalendar.setTimeInMillis() was not possible due to the calendar always wanting to go to 1970.
// GregorianCalendar gc = new GregorianCalendar();
// gc.setTimeInMillis(val);
// this.year = gc.get(GregorianCalendar.YEAR);
// this.month = gc.get(GregorianCalendar.MONTH);
// this.day = gc.get(GregorianCalendar.DAY_OF_MONTH);
// this.hour = gc.get(GregorianCalendar.HOUR);
// this.min = gc.get(GregorianCalendar.MINUTE);
// this.sec = gc.get(GregorianCalendar.SECOND);
// this.msec = gc.get(GregorianCalendar.MILLISECOND);
long seconds = milliseconds / 1000;
long mins = seconds / 60;
long hours = mins / 60;
long days = hours / 24;
long months = days * 12 / 365;
long years = days / 365;
this.msec = milliseconds % 1000;
milliseconds /= 1000;
this.sec = (int)(milliseconds % 60);
milliseconds /= 60;
this.min = (int)(milliseconds % 60);
milliseconds /= 60;
this.hour = (int)(milliseconds % 24);
this.day = (int)(days - (months * 365 / 12));
this.month = (int)(months - (years * 12));
this.year = (int)years;
super.reportChange();
}
/**
* @return the time in milliseconds for the interval data. CraigM:26/06/2008.
*/
public long longValue() {
return this.convertToUnitLong(Constants.DR_MILLISECOND);
}
//TF:Mar 19, 2010: use CloneHelper instead
// public Object clone() {
// return this.clone(false);
// }
//
// public Object clone(boolean pDeep) {
// IntervalData result = new IntervalData();
// this.duplicateIntoTarget(result, pDeep);
// return result;
// }
public void duplicateIntoTarget(IntervalData pData, boolean pDeep) {
super.duplicateIntoTarget(pData, pDeep);
pData.day = this.day;
pData.hour = this.hour;
pData.min = this.min;
pData.month = this.month;
pData.msec = this.msec;
pData.sec = this.sec;
pData.year = this.year;
}
/**
* CraigM:26/06/2008 - This method can be dangerous to use as it is possible to require a long value returned.
*
* @param unit
* @return
*/
public int convertToUnit(int unit) {
return (int)this.convertToUnitLong(unit);
}
/**
* CraigM:26/06/2008 - Fixed many bugs in this method.
*
* @param unit
* @return
*/
public long convertToUnitLong(int unit) {
long result = 0;
switch (unit) {
case Constants.DR_DAY:
result += (long)this.year * 365;
result += (long)this.month * 365 / 12 / 24;
result += (long)this.day;
break;
case Constants.DR_HOUR:
result += (long)this.year * 365 * 24;
result += (long)this.month * 365 / 12;
result += (long)this.day * 24;
result += (long)this.hour;
break;
case Constants.DR_MINUTE:
result += (long)this.year * 365 * 24 * 60;
result += (long)this.month * 365 / 12 * 60;
result += (long)this.day * 24 * 60;
result += (long)this.hour * 60;
result += (long)this.min;
break;
case Constants.DR_SECOND:
result += (long)this.year * 365 * 24 * 60 * 60;
result += (long)this.month * 365 / 12 * 60 * 60;
result += (long)this.day * 24 * 60 * 60;
result += (long)this.hour * 60 * 60;
result += (long)this.min * 60;
result += (long)this.sec;
break;
case Constants.DR_MILLISECOND:
result += (long)this.year * 365 * 24 * 60 * 60 * 1000;
result += (long)this.month * 365 / 12 * 60 * 60 * 1000;
result += (long)this.day * 24 * 60 * 60 * 1000;
result += (long)this.hour * 60 * 60 * 1000;
result += (long)this.min * 60 * 1000;
result += (long)this.sec * 1000;
result += (long)this.msec;
break;
}
return result;
}
public IntervalData subtract(DateTimeData d1, DateTimeData d2){
int elapsedDays = 0;
int elapsedHours = 0;
int elapsedMins = 0;
int elapsedSecs = 0;
GregorianCalendar gc1 = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
gc1.setTime(d2.asDate());
gc2.setTime(d1.asDate());
// TF:20/06/2008:If we're subtracting a greater value from a lesser value, we'll end up with
// a negative value for the value of days, but positive other values
while (gc2.before(gc1)) {
gc2.add(Calendar.DATE, 1);
elapsedDays--;
}
while (gc1.before(gc2)) {
gc1.add(Calendar.DATE, 1);
elapsedDays++;
}
if (gc1.after(gc2)) {
elapsedDays--; // if we have added one day more than needed, remove it
gc1.add(Calendar.DATE, -1);
}
while (gc1.before(gc2)) {
gc1.add(Calendar.HOUR, 1);
elapsedHours++;
}
if (gc1.after(gc2)) {
elapsedHours--;
gc1.add(Calendar.HOUR, -1);
}
while (gc1.before(gc2)) {
gc1.add(Calendar.MINUTE, 1);
elapsedMins++;
}
if (gc1.after(gc2)) {
elapsedMins--;
gc1.add(Calendar.MINUTE, -1);
}
while (gc1.before(gc2)) {
gc1.add(Calendar.SECOND, 1);
elapsedSecs++;
}
if (gc1.after(gc2)) {
elapsedSecs--;
gc1.add(Calendar.SECOND, -1);
}
this.setUnit(0, 0, elapsedDays, elapsedHours, elapsedMins, elapsedSecs, 0);
return this;
}
/**
* Subtract d1 from d2. Store the result in ourselves as well as return ourselves.
*
* CraigM:26/06/2008 - Rewrote method to reuse other methods
*
* @param d2
* @param d1
* @return this
*/
public IntervalData subtract(IntervalData d2, IntervalData d1) {
// CraigM:26/06/2008 - Don't use the GregorianCalendar as it seems to want to set the year to 1970
// GregorianCalendar gc2 = new GregorianCalendar(d2.year, d2.month, d2.day, d2.hour, d2.min, d2.sec);
// gc2.set(GregorianCalendar.MILLISECOND, (int)d2.msec); // Also set the milliseconds. CraigM: 19/02/2008.
// gc2.add(Calendar.YEAR, -d1.year);
// gc2.add(Calendar.MONTH, -d1.month);
// gc2.add(Calendar.DAY_OF_MONTH, -d1.day);
// gc2.add(Calendar.HOUR, -d1.hour);
// gc2.add(Calendar.MINUTE, -d1.min);
// gc2.add(Calendar.SECOND, -d1.sec);
// gc2.add(Calendar.MILLISECOND, (int)-d1.msec);
// this.setValue(gc2);
// return this;
this.setValue(d2.longValue());
this.subtract(d1);
return this;
}
public void setValue(GregorianCalendar gc2) {
this.year = gc2.get(Calendar.YEAR);
this.month = gc2.get(Calendar.MONTH);
this.day = gc2.get(Calendar.DAY_OF_MONTH);
this.hour = gc2.get(Calendar.HOUR);
this.min = gc2.get(Calendar.MINUTE);
this.sec = gc2.get(Calendar.SECOND);
this.msec = gc2.get(Calendar.MILLISECOND);
}
public IntervalData subtract(IntervalData d1){
long diff = this.longValue() - d1.longValue();
this.setValue(diff);
return this;
}
public IntervalData add(IntervalData d1, IntervalData d2){
long sum = d1.longValue() + d2.longValue();
this.setValue(sum);
return this;
}
public IntervalData add(IntervalData d1){
long sum = this.longValue() + d1.longValue();
this.setValue(sum);
return this;
}
public void propertyChange(PropertyChangeEvent arg0) {
// -----------------------------------------------------------------------
// TF:29/01/2010:JCT-640:Changed this to invoke a method on the superclass
// -----------------------------------------------------------------------
this.firePropertyChange("Value", null, this.getTextValue());
}
/**
* Compares original value to specified IntervalData value to determine if original value is equal to specified value.
* @param source
* @return
*/
public BooleanNullable isEqual(IntervalData source){
return new BooleanNullable( (this.longValue() == source.longValue()) );
}
/**
* Compares original value to specified IntervalData value to determine of original value is later than specified value.
* @param source
* @return
*/
public BooleanNullable isGreaterThan(IntervalData source){
return new BooleanNullable( (this.longValue() > source.longValue()) );
}
/**
* Compares original value to specified IntervalData value to determine if original value is earlier than specified value.
* @param source
* @return
*/
public BooleanNullable isLessThan(IntervalData source){
return new BooleanNullable( (this.longValue() < source.longValue()) );
}
/**
* Compares original value to specified IntervalData value, seeking any mismatch.
* @param source
* @return
*/
public BooleanNullable isNotEqual(IntervalData source){
return new BooleanNullable( (this.longValue() != source.longValue()) );
}
/**
* The DifferenceInMonths method replaces the original IntervalValue with the difference between two
* specified DateTimeData values, in months, truncating any remainder.
*
* The result, which is the value of source1 minus source2, is not normalized, and has only the number
* of months set. For example the difference between January 1 and January 31st is 0, whereas the
* difference between January 31st and February 1st is 1.
*
* @param source1
* @param source2
* @return
*/
public IntervalData differenceInMonths(DateTimeData source1, DateTimeData source2) {
if (source1 == null || source2 == null)
data_RaiseNilOperandExcpt();
if (source1.checkNullValue() || source2.checkNullValue()) {
setNull();
super.reportChange();
return (this);
}
int elapsedMonths = 0;
GregorianCalendar gc1 = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
boolean goNegative = false;
// CraigM:20/08/2008 - Swap dates around if necessary
if (source2.isLessThan(source1).getBooleanValue()) {
gc1.setTime(source2.asDate());
gc2.setTime(source1.asDate());
}
else {
goNegative = true;
gc1.setTime(source1.asDate());
gc2.setTime(source2.asDate());
}
// CraigM:20/08/2008 - Throw away the days. This is what Forte did (see above JavaDoc).
gc1.set(GregorianCalendar.DAY_OF_MONTH, 1);
gc2.set(GregorianCalendar.DAY_OF_MONTH, 1);
while (gc1.before(gc2)) {
gc1.add(Calendar.MONTH, 1);
elapsedMonths++;
}
if (gc1.after(gc2)) {
elapsedMonths--; // if we have added one day more than needed, remove it
gc1.add(Calendar.DATE, -1);
}
if (goNegative) {
this.setUnit(0, 0-elapsedMonths, 0, 0, 0, 0, 0);
}
else {
this.setUnit(0, elapsedMonths, 0, 0, 0, 0, 0);
}
return this;
}
/**
* Compares the value attribute of the object specified in the source parameter with the value
* of this object and returns an integer indicating their relative magnitude
* (equals, less than, and so on). If the convert parameter is TRUE, the method
* converts source to a DataValue object if necessary and then does the comparison.
*/
public int compareValue(DataValue source, boolean convert, boolean ignoreCase) {
if (source == null) {
return Constants.DV_CMP_NIL;
}
else if (this.isNull() || source.isNull()) {
return Constants.DV_CMP_NULL;
}
else if (source instanceof IntervalData) {
long thisValue = this.convertToUnitLong(Constants.DR_MILLISECOND);
long otherValue = ((IntervalData)source).convertToUnitLong(Constants.DR_MILLISECOND);
if (thisValue < otherValue)
return Constants.DV_CMP_LT;
else if (thisValue == otherValue)
return Constants.DV_CMP_EQ;
else
return Constants.DV_CMP_GT;
}
else if (convert) {
try {
long thisValue = this.convertToUnitLong(Constants.DR_MILLISECOND);
long otherValue = new IntervalData(source.getTextValue()).convertToUnitLong(Constants.DR_MILLISECOND);
if (thisValue < otherValue)
return Constants.DV_CMP_LT;
else if (thisValue == otherValue)
return Constants.DV_CMP_EQ;
else
return Constants.DV_CMP_GT;
}
catch (Exception e) {
return Constants.DV_CMP_UNCONVERTIBLE;
}
}
return Constants.DV_CMP_UNCONVERTIBLE;
}
/**
* The DifferenceInYears method replaces the original IntervalValue with the difference between two specified DateTimeData values, in years, truncating any remainder.
* The result, which is the value of source1 minus source2, is not normalized, and leaves only the number of years set. For example, the difference between January 1 1993 and December 31st 1993 is 0, whereas the difference between December 31 1993 and January 1st 1994 is 1.
* @param source1
* @param source2
* @return
*/
public IntervalData differenceInYears(DateTimeData source1, DateTimeData source2){
int elapsedYears = 0;
GregorianCalendar gc1 = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
boolean goNegative = false;
// CraigM:20/08/2008 - Swap dates around if necessary
if (source2.isLessThan(source1).getBooleanValue()) {
gc1.setTime(source2.asDate());
gc2.setTime(source1.asDate());
}
else {
goNegative = true;
gc1.setTime(source1.asDate());
gc2.setTime(source2.asDate());
}
// CraigM:20/08/2008 - Throw away the days and months. This is what Forte did (see above JavaDoc).
gc1.set(GregorianCalendar.DAY_OF_MONTH, 1);
gc2.set(GregorianCalendar.DAY_OF_MONTH, 1);
gc1.set(GregorianCalendar.MONTH, 1);
gc2.set(GregorianCalendar.MONTH, 1);
while (gc1.before(gc2)) {
gc1.add(Calendar.YEAR, 1);
elapsedYears++;
}
if (gc1.after(gc2)) {
elapsedYears--; // if we have added one day more than needed, remove it
gc1.add(Calendar.DATE, -1);
}
if (goNegative) {
this.setUnit(0-elapsedYears, 0, 0, 0, 0, 0, 0);
}
else {
this.setUnit(elapsedYears, 0, 0, 0, 0, 0, 0);
}
return this;
}
public int dataType() {
return Constants.DV_DT_INTERVAL;
}
public void decodeValue(TextData text, DataFormat format) {
throw new UnsupportedOperationException("IntervalData.decodeValue() is not implemented");
}
/**
* The Value attribute (TextData) is the same as the TextData attribute defined on DataValue.
* To set the IntervalData value, you use a text value with the following format:
* <code>years:months:days:hours:minutes:seconds:milliseconds</code>
* @return
*/
public TextData getValue(){
return getTextValue();
}
public IntervalData normalize(DateTimeData dt) {
GregorianCalendar gc = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
gc.setTime(dt.theDate);
gc.setLenient(true);
gc.add(Calendar.YEAR, this.year);
gc.add(Calendar.MONTH, this.month);
gc.add(Calendar.DATE, this.day);
gc.add(Calendar.HOUR, this.hour);
gc.add(Calendar.MINUTE, this.min);
gc.add(Calendar.SECOND, this.sec);
gc.add(Calendar.MILLISECOND, (int)this.msec);
_log.debug("1:" + gc.getTime());
gc2.setTime(dt.theDate);
_log.debug("2:" + gc2.getTime());
long diff = gc.getTimeInMillis() - gc2.getTimeInMillis();
_log.debug("diff:" + diff);
int remainder = 0;
this.year = 0;
this.month = 0;
this.day = (int)(diff / msPER_DAY);
remainder = (int)(diff % msPER_DAY);
this.hour = (int)(remainder / msPER_HOUR);
remainder = (int)(remainder % msPER_HOUR);
this.min = (int)(remainder / msPER_MIN);
remainder = (int)(remainder % msPER_MIN);
this.sec = (int)(remainder / msPER_SEC);
this.msec = (int)(remainder % msPER_SEC);
return this;
}
/**
* This method is obsolete. Use the methods of the Stopwatch class instead
*/
@Deprecated
public void setFromClock() {
// Rewrote method to set all values up to day, not just milliseconds. CraigM: 19/02/2008.
// this.msec = System.currentTimeMillis();
long currentTime = System.currentTimeMillis();
int remainder = 0;
this.year = 0;
this.month = 0;
this.day = (int)(currentTime / msPER_DAY);
remainder = (int)(currentTime % msPER_DAY);
this.hour = (int)(remainder / msPER_HOUR);
remainder = (int)(remainder % msPER_HOUR);
this.min = (int)(remainder / msPER_MIN);
remainder = (int)(remainder % msPER_MIN);
this.sec = (int)(remainder / msPER_SEC);
this.msec = (int)(remainder % msPER_SEC);
}
/**
* This variation of the Multiply method multiplies the original IntervalData value by a specified value and replaces the original IntervalData value with the result.
* @param i
*/
public void multiply(int i) {
this.year *= i;
this.month *= i;
this.day *= i;
this.hour *= i;
this.min *= i;
this.sec *= i;
this.msec *= i;
}
/**
* Converts the value to a String the Database understands. Currently only supports Informix.
* @return a String in the DB format
*/
public String asDBString() {
StringBuilder value = new StringBuilder();
if (!hasNullValue) {
// Check if there is years and months, otherwise out in day format
if (this.year != 0 || this.month != 0) {
value.append(year);
value.append("-");
value.append(month);
} else if (this.day != 0 || this.hour != 0 || this.min != 0 || this.sec != 0 || this.msec != 0) {
value.append(this.day);
value.append(" ");
if (this.hour != 0 || this.min != 0 || this.sec != 0 || this.msec != 0) {
value.append(this.hour);
/* CS Chan 08/07/08 both hour and minute should be included if either one is present
}
if (this.min != 0 || this.sec != 0 || this.msec != 0) {
*/
value.append(":");
value.append(this.min);
}
if (this.sec != 0 || this.msec != 0) {
value.append(":");
value.append(this.sec);
}
if (this.msec != 0) {
value.append(".");
value.append(this.msec);
}
}
}
return value.toString();
}
/**
* Converts the value to a String a user can understand.
* @return a String in the human readable format e.g. 1min 2sec 3ms
*/
public String asReadableString() {
StringBuilder value = new StringBuilder();
// if it's not empty, only show the units with a value in them
if (!hasNullValue) {
if (this.year != 0) {
value.append(year);
if (this.year == 1){
value.append("year ");
} else {
value.append("years ");
}
}
if (this.month != 0) {
value.append(month);
if (this.month == 1){
value.append("month ");
} else {
value.append("months ");
}
}
if (this.day != 0) {
value.append(day);
if (this.day == 1){
value.append("day ");
} else {
value.append("days ");
}
}
if (this.hour != 0) {
value.append(hour);
if (this.hour == 1){
value.append("hour ");
} else {
value.append("hours ");
}
}
if (this.min != 0) {
value.append(min);
value.append("min ");
}
if (this.sec != 0) {
value.append(sec);
value.append("sec ");
}
if (this.msec != 0) {
value.append(msec);
value.append("ms");
}
}
return value.toString();
}
}