
edu.uvm.ccts.arden.model.Duration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of arden-model Show documentation
Show all versions of arden-model Show documentation
The Java model used to represent Arden objects
/*
* Copyright 2015 The University of Vermont and State
* Agricultural College, Vermont Oxford Network, and The University
* of Vermont Medical Center. All rights reserved.
*
* Written by Matthew B. Storer
*
* This file is part of Arden Model.
*
* Arden Model is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Arden Model is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Arden Model. If not, see .
*/
package edu.uvm.ccts.arden.model;
import edu.uvm.ccts.common.exceptions.UnhandledClassException;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
/**
* An Arden-duration object
*
* The duration data type signifies an interval of time that is not anchored to any particular point in absolute time.
* There are no duration constants. Instead one builds durations using the duration operators (see Section 9.10.7). For
* example, 1 day, 45 seconds, and 3.2 months are durations.
* @see 8.5
*
* Sub-types
* The duration data type has two sub-types: months and seconds. The reason for the division is that the number of
* seconds in a month or in a year depends on the starting date. Durations of months and years are expressed as months.
* Durations of seconds, minutes, hours, days, and weeks are expressed as seconds. There are no complex durations; the
* sub-type must be either months or seconds, but not both. For both types of durations, the duration amount may be a
* floating point value.
*
* The printing of a duration (that is, its string version) is independent of its internal representation. The health
* care provider who reads the result of an MLM may not realize that there are two sub-types of durations. How
* durations are printed is location-specific. For example, the string version of 6E+08 seconds might be 19.01 years.
* See Section 9.8.
* @see 8.5.1
*/
public abstract class Duration extends PrimaryTimeDataType implements Comparable,
ITimeComponent {
public static final int SECOND = 1;
public static final int SEC_IN_MINUTE = 60;
public static final int SEC_IN_HOUR = 60 * SEC_IN_MINUTE;
public static final int SEC_IN_DAY = 24 * SEC_IN_HOUR;
public static final int SEC_IN_WEEK = 7 * SEC_IN_DAY;
public static final int SEC_IN_MONTH = 2629746; // spec 8.5.2.4
public static final int SEC_IN_YEAR = 12 * SEC_IN_MONTH;
public static Duration copyOf(Duration d) {
if (d == null) return null;
else if (d instanceof MonthsDuration) return ((MonthsDuration) d).copy();
else if (d instanceof SecondsDuration) return ((SecondsDuration) d).copy();
else throw new UnhandledClassException("cannot cast " + d.getClass().getName() + " to Duration");
}
/**
* When representing a {@link Duration} as a {@link Time}, the number of seconds represented by the duration is
* added to the time that the MLM became executable.
* @see 13.3.3.1
* @return
*/
@Override
public Time asTime(Time relativeToTime) {
return relativeToTime.add(this);
}
public abstract long getSeconds();
public abstract Duration add(Duration d);
public abstract Duration subtract(Duration d);
public abstract Duration multiply(ANumber n);
public abstract Duration multiply(Number n);
/**
* Compares this object to another as an identity comparison, in which the primary time of the objects are
* considered.
* @param o
* @return {@code true} if {@code this} and {@code o} have the same value and the same primary
* time.
*/
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (o.getClass() != getClass()) return false;
Duration d = (Duration) o;
return new EqualsBuilder()
.append(primaryTime, d.primaryTime)
.append(getSeconds(), d.getSeconds())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(53, 109)
.append(primaryTime)
.append(getSeconds())
.toHashCode();
}
/**
* Compares this object to another, considering only the value of the object, and not the primary time.
* @param o
* @return {@code true} if {@code this} and {@code o} have the same value.
*/
@Override
public boolean hasValue(ADataType o) {
if (o == null) return false;
if (o == this) return true;
if (o.getClass() != getClass()) return false;
return getSeconds() == ((Duration) o).getSeconds();
}
@Override
public int compareTo(Duration d) {
if (this == d) return 0;
long a = getSeconds();
long b = d.getSeconds();
if (a < b) return -1;
else if (a > b) return 1;
assert this.equals(d) : "compareTo inconsistent with equals.";
return 0;
}
@Override
public Object toJavaObject() {
return getSeconds();
}
public Duration divide(ANumber n) {
long left = getSeconds();
if (n.isWholeNumber()) {
long right = n.asWholeNumber();
if (right == 0) return null;
else return new SecondsDuration(left / right);
} else {
double right = n.asFractionalNumber();
if (right == 0) return null;
else return new SecondsDuration((long) (left / right));
}
}
public ANumber divide(Duration d) {
long left = getSeconds();
long right = d.getSeconds();
if (right == 0) return null;
else return new ANumber(left / right);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy