/*
* @(#)$Id: BigTimeDurationValueType.java,v 1.9 2001/06/19 22:42:36 Bear Exp $
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun Microsystems, Inc.
* Use is subject to license terms.
*
*/
package com.sun.msv.datatype.xsd.datetime;
import java.math.BigInteger;
import java.math.BigDecimal;
import com.sun.msv.datatype.xsd.Comparator;
/**
* ITimeDurationValueType implementation that can hold all lexically legal
* timeDuration value.
*
* @author Kohsuke KAWAGUCHI
*/
public class BigTimeDurationValueType implements ITimeDurationValueType {
protected BigInteger year;
protected BigInteger month;
protected BigInteger day;
protected BigInteger hour;
protected BigInteger minute;
protected BigDecimal second;
private static final BigDateTimeValueType[] testInstance =
new BigDateTimeValueType[]{
new BigDateTimeValueType(
new BigInteger("1696"), 8/*Sep*/, 0/*1st*/, 0,0, new BigDecimal(0), TimeZone.GMT ),
new BigDateTimeValueType(
new BigInteger("1697"), 1/*Feb*/, 0/*1st*/, 0,0, new BigDecimal(0), TimeZone.GMT ),
new BigDateTimeValueType(
new BigInteger("1903"), 2/*Mar*/, 0/*1st*/, 0,0, new BigDecimal(0), TimeZone.GMT ),
new BigDateTimeValueType(
new BigInteger("1903"), 6/*Jul*/, 0/*1st*/, 0,0, new BigDecimal(0), TimeZone.GMT ) };
public boolean equals( Object o ) {
return equals( (ITimeDurationValueType)o );
}
public boolean equals( ITimeDurationValueType o ) {
return compare(o)==Comparator.EQUAL;
}
public String toString() {
return ((year==null||year.signum()<0)?"-":"")+
"P"+nullAsZero(year).abs()+"Y"+
nullAsZero(month)+"M"+
nullAsZero(day)+"DT"+
nullAsZero(hour)+"H"+
nullAsZero(minute)+"M"+
(second==null?"":second.toString())+"S";
}
private BigInteger nullAsZero(BigInteger o) {
if(o==null) return BigInteger.ZERO;
else return o;
}
/**
* hash code has to be consistent with equals method.
*/
public int hashCode() {
// 400Y = 365D*303 + 366D*97 = 146097D = 3506328 hours
// = 210379680 minutes
// and no other smaller years have their equivalent days.
// hashCode is very complex because it has to consistent with the behavior of equals method.
return nullAsZero(day).multiply(Util.the24)
.add( nullAsZero(hour) ).multiply(Util.the60)
.add( nullAsZero(minute) ).mod(Util.the210379680).hashCode();
}
public int compare( ITimeDurationValueType o ) {
if(!(o instanceof BigTimeDurationValueType) )
o = o.getBigValue();
return compare( this, (BigTimeDurationValueType)o );
}
static private int compare( BigTimeDurationValueType lhs, BigTimeDurationValueType rhs ) {
boolean less=false,greater=false,noDeterminate=false;
for( int i=0; i<testInstance.length; i++ ) {
BigDateTimeValueType l = (BigDateTimeValueType)testInstance[i].add(lhs);
BigDateTimeValueType r = (BigDateTimeValueType)testInstance[i].add(rhs);
int v = BigDateTimeValueType.compare(l,r);
if(v<0) less=true;
if(v>0) greater=true;
if(v==0) {
if(!l.equals(r)) noDeterminate=true;
}
}
if(noDeterminate) return Comparator.UNDECIDABLE;
if(less && greater) return Comparator.UNDECIDABLE;
if(less) return Comparator.LESS; // lhs<rhs
if(greater) return Comparator.GREATER; // lhs>rhs
return Comparator.EQUAL;
}
public BigTimeDurationValueType getBigValue() { return this; }
public BigTimeDurationValueType(
BigInteger year, BigInteger month, BigInteger day,
BigInteger hour, BigInteger minute, BigDecimal second ) {
this.year = year!=null?year:BigInteger.ZERO;
this.month = month!=null?month:BigInteger.ZERO;
this.day = day!=null?day:BigInteger.ZERO;
this.hour = hour!=null?hour:BigInteger.ZERO;
this.minute = minute!=null?minute:BigInteger.ZERO;
this.second = second!=null?second:new BigDecimal(0);
}
public static BigTimeDurationValueType fromMinutes( int minutes )
{ return fromMinutes(Util.int2bi(minutes)); }
public static BigTimeDurationValueType fromMinutes( BigInteger minutes )
{ return new BigTimeDurationValueType(null,null,null,null,minutes,null); }
}