/************************************************************************** * File name : AbsoluteTime.java * * This file is part a SCJ Level 0 and Level 1 implementation, * based on SCJ Draft, Version 0.94 25 June 2013. * * It is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This SCJ Level 0 and Level 1 implementation 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this SCJ Level 0 and Level 1 implementation. * If not, see <http://www.gnu.org/licenses/>. * * Copyright 2012 * @authors Anders P. Ravn, Aalborg University, DK * Stephan E. Korsholm and Hans Søndergaard, * VIA University College, DK *************************************************************************/ package javax.realtime; import javax.safetycritical.annotate.SCJAllowed; /** * An object that represents a specific point in time given by milliseconds * plus nanoseconds past some point in time fixed by the clock. * For the default real-time clock the fixed point * is the implementation dependent Epoch.<br> * * The correctness of the Epoch as a time base depends on the real-time clock synchronization * with an external world time reference. This representation was designed to be compatible with * the standard Java representation of an absolute time in the <code>java.util.Date</code> class. <br> * * A time object in normalized form represents negative time if both components are nonzero and * negative, or one is nonzero and negative and the other is zero. For add and subtract negative * values behave as they do in arithmetic.<br> * * <b>Caution</b>: This class is explicitly unsafe in multi-threaded situations when it is being * changed. No synchronization is done. It is assumed that users of this class who are mutating * instances will be doing their own synchronization at a higher level. * * @version 1.2; - December 2013 * * @author Anders P. Ravn, Aalborg University, * <A HREF="mailto:apr@cs.aau.dk">apr@cs.aau.dk</A>, <br> * Hans Søndergaard, VIA University College, Denmark, * <A HREF="mailto:hso@viauc.dk">hso@via.dk</A> * * @scjComment * - semantic issue: Java arithmetic is assumed for numeric values. * Thus there is no concept of overflow in milliseconds. <br> * - semantic issue: If <code>AbsoluteTime</code> time in subtract is null, * an <code>IllegalArgumentException</code> is thrown. <br> * - semantic issue: If clocks are different in <code>AbsoluteTime</code> subtract, * an <code>IllegalArgumentException</code> is thrown. */ @SCJAllowed public class AbsoluteTime extends HighResolutionTime { /** * Equivalent to <code>new AbsoluteTime(0,0)</code>. <br> * The clock association is implicitly made with the real-time clock. */ public AbsoluteTime() { this(0L, 0); } /** * Constructs an <code>AbsoluteTime</code> object with millisecond and * nanosecond components past the real-time clock's Epoch. <br> * The actual value is the result of parameter normalization.<br> * * The clock association is implicitly made with the real-time clock. <br> * * @param millis is the desired value for the millisecond component. * The actual value is the result of parameter normalization. * @param nanos is the desired value for the nanosecond component. * The actual value is the result of parameter normalization. */ public AbsoluteTime(long millis, int nanos) { super(millis, nanos, Clock.getRealtimeClock()); } /** * Make a new <code>AbsoluteTime</code> object from the given <code>AbsoluteTime</code> object. <br> * * This constructor requires that the <code>time.getClock()<code> argument * resides in a scope that encloses the current scope.<br> * * @param time the object copied * * @throws IllegalArgumentException if the <code>time</code> parameter is null. */ public AbsoluteTime(AbsoluteTime time) { this(); if (time == null) throw new IllegalArgumentException("null parameter"); set(time); } /** * Constructs an <code>AbsoluteTime</code> object with time millisecond * and nanosecond components past the clock's Epoch. <br> * * This constructor requires that the <code>>clock</code> object resides * in a scope that encloses the current scope. <br> * * @param millis is the desired value for the millisecond component. * * @param nanos is the desired value for the nanosecond component. * * @param clock is the desired value for the clock. */ public AbsoluteTime(long millis, int nanos, Clock clock) { super(millis, nanos, clock); } /** * Equivalent to <code>AbsoluteTime(0,0,clock)</code>. * * @param clock is the desired value for the clock. */ public AbsoluteTime(Clock clock) { this(0, 0, clock); } /** * Creates a new object representing the result of adding millis and nanos * to the values from <code>this</code> and normalizing the result. * The result will have the same clock association as <code>this</code>. * * @param millis is the number of milliseconds to be added to <code>this</code>. * * @param nanos is the number of nanoseconds to be added to <code>this</code>. * * @return a new <code>AbsoluteTime</code> object whose time is the * normalization of <code>this </code> plus <code>millis</code> and <code>nanos</code>. */ public AbsoluteTime add(long millis, int nanos) { return new AbsoluteTime(this.millis + millis, this.nanos + nanos, this.clock); } /** * Returns an object containing the value resulting from adding <code>millis</code> and <code>nanos</code> to * the values from <code>this</code> and normalizing the result. If <code>dest</code> is not null, the result is * placed there and returned. Otherwise, a new object is allocated for the result. <br> * * The result will have the same clock association as <code>this</code>, * and the clock association with <code>dest</code> is ignored. * * @param millis is the number of milliseconds to be added to <code>this</code>. * @param nanos is the number of nanoseconds to be added to <code>this</code>. * @param dest if not null, the result is placed there and returned. * Otherwise, a new object is allocated for the result. * * @return the result of the normalization of <code>this</code> plus <code>millis</code> and nanos</code> * in <code>dest</code> if it is not null, otherwise the result is returned in a newly allocated object. */ public AbsoluteTime add(long millis, int nanos, AbsoluteTime dest) { if (dest == null) dest = new AbsoluteTime(this.clock); dest.set(this.millis + millis, this.nanos + nanos); return dest; } /** * Creates a new instance of <code>AbsoluteTime</code> representing the result of * adding <code>time</code> to the value of <code>this</code> and normalizing the result.<br> * * @param time the time to add to <code>this</code>. * * @return a new object whose time is the normalization of <code>this</code> plus the parameter <code>time</code>. * * @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated with the * <code>time</code> parameter are different, or when the <code>time</code> parameter is null. */ public AbsoluteTime add(RelativeTime time) { if (time == null) throw new IllegalArgumentException("time is null"); if (time.getClock() != getClock()) throw new IllegalArgumentException("clock mismatch"); return new AbsoluteTime(this.millis + time.getMilliseconds(), this.nanos + time.getNanoseconds(), this.clock); } /** * Returns an object containing the value resulting from adding <code>time</code> to the value of * <code>this</code> and normalizing the result. If <code>dest</code> is not null, the result * is placed there and returned. Otherwise, a new object is allocated for the result. * * The clock associated with <code>this</code> and the clock associated with the <code>time</code> parameter * must be the same, and it is used for the result. A clock associated with the <code>dest</code> parameter * is ignored. * * @param time is the time to add to <code>this</code>. * @param dest is not null, the result is placed there and returned. * Otherwise, a new object is allocated for the result. * @return the result in <code>dest</code> if it is not null, * otherwise the result is returned in a newly allocated object. * @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock * associated with the <code>time</code> parameter are different, or when the <code>time</code> parameter is null. */ public AbsoluteTime add(RelativeTime time, AbsoluteTime dest) { if (time == null) throw new IllegalArgumentException("time is null"); if (time.getClock() != getClock()) throw new IllegalArgumentException("clock mismatch"); return add(time.getMilliseconds(), time.getNanoseconds(), dest); } /** * Creates a new instance of <code>RelativeTime</code> representing the result of subtracting <code>time</code> * from the value of <code>this</code> and normalizing the result. * * The clock associated with <code>this</code> and the clock associated with the <code>time</code> parameter * must be the same, and it is used for the result. * * @param time is the time to subtract from <code>this. * @return a new object whose time is the normalization of <code>this</code> minus <code>time</code>. * @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated * with the <code>time</code> parameter are different, or when the <code>time</code> parameter is null. */ public RelativeTime subtract(AbsoluteTime time) { if (time == null) { throw new IllegalArgumentException("time is null"); } if (this.clock != time.clock) { throw new IllegalArgumentException("clock mismatch"); } return new RelativeTime(this.millis - time.getMilliseconds(), this.nanos - time.getNanoseconds(), this.clock); } /** * Returns an object containing the value resulting from subtracting <code>time</code> from the value * of <code>this</code> and normalizing the result. If <code>dest</code> is not null, the result is placed * there and returned. Otherwise, a new object is allocated for the result. <br> * * The clock associated with <code>this</code> and the clock associated with the <code>time</code> parameter * must be the same, and it is used for the result. The clock associated with the <code>dest</code> parameter is ignored. * * @param time is the time to subtract from <code>this</code>. * @param dest if not null, the result is placed there and returned. * * @return the result of the normalization of <code>this</code> minus <code>time</code> in <code>dest</code> * if it is not null, otherwise the result is returned in a newly allocated object. * @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated * with the <code>time</code> parameter are different, or when the <code>time</code> parameter is null. */ public RelativeTime subtract(AbsoluteTime time, RelativeTime dest) { if (time == null) throw new IllegalArgumentException("time is null"); if (this.clock != time.clock) throw new IllegalArgumentException("clock mismatch"); if (dest != null) { dest.set(this.millis - time.getMilliseconds(), this.nanos - time.getNanoseconds()); } else { dest = this.subtract(time); } return dest; } /** * Creates a new instance of <code>AbsoluteTime</code> representing the result of subtracting <code>time</code> * from the value of <code>this</code> and normalizing the result. <br> * * The clock associated with <code>this</code> and the clock associated with the <code>time</code> parameter * must be the same, and it is used for the result. * * @param time is the time to subtract from <code>this</code>. * * @return a new <code>AbsoluteTime</code> object whose time is the normalization of <code>this</code> minus * <code>time</code>. * * @throws IllegalArgumentException if the clock associated with <code>this</code> and * the clock associated with the <code>time<Code> parameter are different or when * the <code>time</code> parameter is null. */ public AbsoluteTime subtract(RelativeTime time) { if (time == null) throw new IllegalArgumentException("time is null"); if (time.getClock() != getClock()) throw new IllegalArgumentException("clock mismatch"); return new AbsoluteTime(this.millis - time.getMilliseconds(), this.nanos - time.getNanoseconds(), this.clock); } /** * Returns an object containing the value resulting from subtracting <code>time</code> from the value of <code>this</this> * and normalizing the result. If <code>dest</code> is not null, the result is placed * there and returned. Otherwise, a new object is allocated for the result. <br> * * The clock associated with <code>this</code> and the clock associated with the <code>time</code> parameter * must be the same, and it is used for the result. The clock associated with the <code>dest</code> parameter is ignored. * * @param time is the time to subtract from <code>this</code>. * @param dest if not null, the result is placed there and returned. * @return the result of the normalization of <code>this</code> minus <code>time</code> in <code>dest</code> * if it is not null, otherwise the result is returned in a newly allocated object. * @throws IllegalArgumentException if the clock associated with <code>this</code> and the clock associated * with the <code>time</code> parameter are different, or when the <code>time</code> parameter is null. */ public AbsoluteTime subtract(RelativeTime time, AbsoluteTime dest) { if (time == null) throw new IllegalArgumentException("time is null"); if (this.clock != time.clock) throw new IllegalArgumentException("clock mismatch"); if (dest == null) { dest = new AbsoluteTime(this.millis - time.getMilliseconds(), this.nanos - time.getNanoseconds(), this.clock); } else { dest.set(this.millis - time.getMilliseconds(), this.nanos - time.getNanoseconds()); } return dest; } }