All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xdef.sys.SDuration Maven / Gradle / Ivy

The newest version!
package org.xdef.sys;

import org.xdef.msg.SYS;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Calendar;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;

/** Provides operations with date and time periods (see ISO 8061).
 * This class implements abstract methods from javax.xml.datatype.Duration.
 * @author Vaclav Trojan
 */
public class SDuration extends Duration implements Comparable {

	private int _years;
	private int _months;
	private int _days;
	private int _hours;
	private int _minutes;
	private int _seconds;
	private double _fraction;
	private int _recurrence = 1;
	private int _negative = 1;
	private SDatetime _start;
	private SDatetime _end;

	/** Creates a new empty instance of SDuration. */
	SDuration() {}

	/** Creates a new instance of SDuration as clone created from parameter.
	 * @param duration the parameter from which this clone will be generated.
	 */
	public SDuration(final SDuration duration) {copyValues(duration);}

	private void copyValues(final SDuration duration) {
		if (duration._start != null) {
			_start = new SDatetime(duration._start);
		}
		if (duration._end != null) {
			_end = new SDatetime(duration._end);
		}
		 _years = duration._years;
		_months = duration._months;
		_days = duration._days;
		_hours = duration._hours;
		_minutes = duration._minutes;
		_seconds = duration._seconds;
		_fraction = duration._fraction;
		_recurrence = duration._recurrence;
		_negative = duration._negative;
	}

	/** Creates a new instance of SDuration with start and end.
	 * @param start start of period (may be null).
	 * @param end end of period (may be null).
	 */
	public SDuration(final SDatetime start, final SDatetime end) {
		_start = start;
		_end = end;
	}

	/** Creates a new instance of SDuration from source string.
	 * @param source source data duration in ISO 8601 format.
	 * @throws SRuntimeException if an error occurs.
	 */
	public SDuration(final String source) throws SRuntimeException {
		StringParser p = new StringParser(source, new NullReportWriter(true));
		try {
			if (p.chkDuration(false) && p.eos()) {
				copyValues(p.getParsedSDuration());
			} else {
				//Icorrect format of time period
				throw new SRuntimeException(SYS.SYS056);
			}
		} catch (SRuntimeException ex) {
			if (ex instanceof SThrowable) {
				throw new SRuntimeException(((SThrowable) ex).getReport());
			} else {
				//Program exception&{0}{: }
				throw new SRuntimeException(SYS.SYS036, ex);
			}
		}
	}

	/** Get next datetime computed from parameters. If start is not defined then
	 * actual datetime is used.
	 * @return next datetime computed from parameters.
	 */
	public SDatetime getNextTime() {
		if (_start == null) {
			return getNextTime(SDatetime.now());
		}
		return getNextTime(_start);
	}

	/** add datetime computed from argument.
	 * @param datetime datetime to which interval is added.
	 * @return next datetime computed from argument.
	 */
	public SDatetime getNextTime(final SDatetime datetime) {
		SDatetime result = addDate(datetime);
		if (_end != null) {
			if (!_end.isAfter(result)) {
				return null;
			}
		}
		return result;
	}

	/** Set negative switch.
	 * @param negative value of switch.
	 */
	public void setNegative(final boolean negative) {
		synchronized(this) {
			_negative = negative?-1:1;
		}
	}

	/** Check if value is negative.
	 * @return true if value is negative.
	 */
	public boolean isNegative() {return _negative == -1;}

	/** Set number of recurrences.
	 * @param recurrence number of recurrences.
	 */
	public void setRecurrence(final int recurrence) {
		synchronized(this) {
			_recurrence = recurrence;
		}
	}

	/** Get number of recurrences.
	 * @return number of recurrences or 0.
	 */
	public int getRecurrence() {return _recurrence;}

	/** Set start of period.
	 * @param start datetime specifying start of period.
	 */
	public void setStart(final SDatetime start) {
		synchronized(this) {
			_start = start;
		}
	}

	/** Get start of period.
	 * @return start datetime.
	 */
	public SDatetime getStart() {return _start;}

	/** Set end of period.
	 * @param end datetime specifying end of period.
	 */
	public void setEnd(final SDatetime end) {
		synchronized(this) {
			_end = end;
		}
	}

	/** Get end of period.
	 * @return end datetime.
	 */
	public SDatetime getEnd() {return _end;}

	/** Set number of years of period. Weeks parameter is cleared if specified.
	 * @param years number of years.
	 */
	public void setYears(final int years) {
		synchronized(this) {
			_years = years;
		}
	}

	@Override
	/** Get number of years of period.
	 * @return number of years.
	 */
	public int getYears() {return _years;}

	/** Set number of months of period. Weeks parameter is cleared if specified.
	 * @param months number of months.
	 */
	public void setMonths(final int months) {
		synchronized(this) {
			_months = months;
		}
	}

	@Override
	/** Get number of months of period.
	 * @return number of months.
	 */
	public int getMonths() {return _months;}

	/** Set number of days of period. Weeks parameter is cleared if specified.
	 * @param days number of days.
	 */
	public void setDays(final int days) {
		synchronized(this) {
			_days = days;
		}
	}

	@Override
	/** Get number of days of period.
	 * @return number of days.
	 */
	public int getDays() {return _days;}

	/** Set number of hours of period.
	 * @param hours number of hours.
	 */
	public void setHours(final int hours) {
		synchronized(this) {
			_hours = hours;
		}
	}

	@Override
	/** Get number of hours of period.
	 * @return number of hours.
	 */
	public int getHours() {return _hours;}

	/** Set number of minutes of period.
	 * @param minutes number of minutes.
	 */
	public void setMinutes(final int minutes) {
		synchronized(this) {
			_minutes = minutes;
		}
	}

	@Override
	/** Get number of minutes of period.
	 * @return number of minutes.
	 */
	public int getMinutes() {return _minutes;}

	/** Set number of seconds of period.
	 * @param seconds number of seconds.
	 */
	public void setSeconds(final int seconds) {
		synchronized(this) {
			_seconds = seconds;
		}
	}

	@Override
	/** Get number of seconds of period.
	 * @return seconds.
	 */
	public int getSeconds() {return _seconds;}

	/** Set number of milliseconds of period.
	 * @param milliseconds number of milliseconds.
	 */
	public void setMilliseconds(final int milliseconds) {
		synchronized(this) {
			_fraction = milliseconds * 0.001D;
		}
	}

	/** Get number of milliseconds of period.
	 * @return milliseconds.
	 */
	public int getMilliseconds() {
		return (int) java.lang.Math.round(_fraction * 1000.0D);
	}

	/** Set number of nanoseconds of period.
	 * @param nanoseconds number of nanoseconds.
	 */
	public void setNanoseconds(final int nanoseconds) {
		synchronized(this) {
			_fraction = nanoseconds * 0.000000001D;
		}
	}

	/** Get number of nanoseconds of period.
	 * @return nanoseconds.
	 */
	public int getNanoseconds() {
		return (int) java.lang.Math.round(_fraction * 1000000000.0D);
	}

	/** Set fraction of second.
	 * @param fraction of second.
	 * @throws SRuntimeException if fraction is out of interval.
	 */
	public void setFraction(final double fraction)
	throws SRuntimeException {
		if (fraction < 0 || fraction >= 1.0D) {
			throw new SRuntimeException(SYS.SYS072, //Data error&{0}{: }
				"fraction of second out of interval 0..1");
		} else {
			synchronized(this) {
				_fraction = fraction;
			}
		}
	}

	/** Get fraction of second.
	 * @return Double with fraction of second or null.
	 */
	public double getFraction() {return _fraction;}

	private void durationToString(final StringBuilder sb) {
		boolean empty = true;
		if (_years != 0 || _months != 0 || _days != 0) {
			if (_negative == -1) {
				sb.append('-');
			}
			sb.append('P');
			empty = false;
			if (_years != 0) {
				sb.append(String.valueOf(_years));
				sb.append('Y');
			}
			if (_months != 0) {
				sb.append(String.valueOf(_months));
				sb.append('M');
			}
			if (_days != 0) {
				sb.append(String.valueOf(_days));
				sb.append('D');
			}
		}
		if (_hours != 0 || _minutes != 0 || _seconds != 0) {
			if (empty) {
				if (_negative == -1) {
					sb.append('-');
				}
				sb.append('P');
//				empty = false;
			}
			sb.append("T");
			if (_hours != 0) {
				sb.append(String.valueOf(_hours));
				sb.append('H');
			}
			if (_minutes != 0) {
				sb.append(String.valueOf(_minutes));
				sb.append('M');
			}
			if (_seconds != 0 || _fraction != 0.0D) {
				if (_fraction > 0.0D) {
					sb.append(String.valueOf(_fraction + _seconds));
				} else {
					sb.append(String.valueOf(_seconds));
				}
				sb.append('S');
			}
		}
	}

	@Override
	/** Get ISO 8601 format of duration.
	 * @return ISO 8601 format of this object.
	 */
	public String toString() {
		StringBuilder sb = new StringBuilder();
		if (_recurrence > 1) {
			sb.append('R').append(_recurrence).append('/');
		}
		if (_start != null) {
			sb.append(_start.toString());
		}
		if (_years != 0 || _months != 0 || _days != 0 ||
			_hours != 0 || _minutes != 0 || _seconds != 0) {
			if (_start != null) {
				sb.append('/');
			}
			durationToString(sb);
		}
		if (_end != null) {
			sb.append('/');
			sb.append(_end.toString());
		}
		return sb.toString();
	}

	/** Clone SDuration object.
	 * @return new SDuration object as a clone this one.
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		super.clone();
		return new SDuration(this);
	}

	@Override
	/** Partial order relation comparison with this SDuration
	 * instance.
	 * 

Comparison result must be in accordance with * W3C * XML Schema 1.0 Part 2, Section 3.2.7.6.2, * Order relation on duration. *

Return: *

    *
  • -1 if this SDuration is shorter than parameter rhs *
  • 0 if this SDuration is equal to parameter rhs *
  • +1 if this SDuration is longer than parameter rhs *
* @param other duration to compare * @return the relationship between this SDuration * and other parameter. * @throws NullPointerException if hs is null. * @throws SIllegalArgumentException if this object is not comparable * with the argument rhs. */ public int compareTo(final SDuration other) throws NullPointerException, SIllegalArgumentException { if (_start == null && other._start == null) { int i,j,k,l; i = compare(other, new SDatetime(1696, 9, 1)); j = compare(other, new SDatetime(1697, 2, 1)); k = compare(other, new SDatetime(1903, 3, 1)); l = compare(other, new SDatetime(1903, 7, 1)); if (i == j && i == k && i == l) { if (i == 0) { return _fraction == other._fraction ? 0 : _fraction < other._fraction ? -1 : 1; } else { return i; } } //Incomparable arguments throw new SIllegalArgumentException(SYS.SYS085); } if (_start == null) { return 1; } else if (other._start == null) { return -1; } return addDate(_start).compareTo(other.addDate(other._start)); } private int compare(final SDuration other, final SDatetime d) { SDatetime thisD = addDate(d); SDatetime otherD = other.addDate(d); return thisD.compareTo(otherD); } @Override public boolean equals(final Object obj) { return (obj != null && obj instanceof SDuration) ? equals((SDuration) obj) : false; } /** Compare is this duration object and the other duration object are equal. * @param other the other duration object. * @return true if is this duration object and the other duration object * are equal. */ public boolean equals(SDuration other) {return compareTo(other) == 0;} private SDatetime addDate(SDatetime S) { if (_negative < 0) { return S.add(-_years, -_months, -_days, -_hours, -_minutes, -_seconds, -_fraction); } else { return S.add(_years, _months, _days, _hours, _minutes, _seconds, _fraction); } } public void writeObj(final SObjectWriter w) throws IOException { w.writeInt(_years); w.writeInt(_months); w.writeInt(_days); w.writeInt(_hours); w.writeInt(_minutes); w.writeInt(_seconds); w.writeDouble(_fraction); w.writeInt(_recurrence); w.writeInt(_negative); w.writeSDatetime(_start); w.writeSDatetime(_end); } public static SDuration readObj(final SObjectReader r) throws IOException { SDuration x = new SDuration(); x._years = r.readInt(); x._months = r.readInt(); x._days = r.readInt(); x._hours = r.readInt(); x._minutes = r.readInt(); x._seconds = r.readInt(); x._fraction = r.readDouble(); x._recurrence = r.readInt(); x._negative = r.readInt(); x._start = r.readSDatetime(); x._end = r.readSDatetime(); return x; } @Override public int hashCode() { synchronized(this) { int result = _start == null ? 0 : _start.hashCode(); result += _end == null ? 0 : 3*_end.hashCode(); return 5*(result + 7*(_years + 13*(_months + 17*(_days + 19*(_hours + 23*(_minutes + 29*(_seconds + 31*(_recurrence + (_fraction == 0.0D ? 0 : 37) + (_negative == -1?1:0))))))))); } } //////////////////////////////////////////////////////////////////////////////// // Implementation of javax.xml.datatype.Duration //////////////////////////////////////////////////////////////////////////////// @Override /** getSignum of value. * @return true if and only if the interval is negative. */ public int getSign() {return _negative;} @Override public Number getField(final DatatypeConstants.Field field) { if (DatatypeConstants.YEARS.getId() == field.getId()) { return _years*_negative; } if (DatatypeConstants.MONTHS.getId() == field.getId()) { return _months*_negative; } if (DatatypeConstants.DAYS.getId() == field.getId()) { return _days*_negative; } if (DatatypeConstants.HOURS.getId() == field.getId()) { return _hours*_negative; } if (DatatypeConstants.MINUTES.getId() == field.getId()) { return _minutes*_negative; } if (DatatypeConstants.SECONDS.getId() == field.getId()) { return _seconds*_negative; } throw new SUnsupportedOperationException("Field: " + field); } @Override public boolean isSet(final DatatypeConstants.Field field) { if (DatatypeConstants.YEARS.getId() == field.getId()) { return _years != 0; } if (DatatypeConstants.MONTHS.getId() == field.getId()) { return _months != 0; } if (DatatypeConstants.DAYS.getId() == field.getId()) { return _days != 0; } if (DatatypeConstants.HOURS.getId() == field.getId()) { return _hours != 0; } if (DatatypeConstants.MINUTES.getId() == field.getId()) { return _minutes != 0; } if (DatatypeConstants.SECONDS.getId() == field.getId()) { return _seconds != 0; } throw new SUnsupportedOperationException("Field: " + field); } @Override public Duration add(final Duration rhs) { throw new SUnsupportedOperationException(); } @Override public void addTo(final Calendar calendar) { throw new SUnsupportedOperationException(); } @Override public Duration multiply(final BigDecimal factor) { throw new SUnsupportedOperationException(); } @Override public Duration negate() { SDuration x = new SDuration(this); x._negative = -_negative; return x; } @Override public Duration normalizeWith(final Calendar startTimeInstant) { throw new SUnsupportedOperationException(); } @Override public int compare(final Duration duration) { if (duration instanceof SDuration) { return compareTo((SDuration) duration); } throw new SIllegalArgumentException( "Compare not supported for " + duration); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy