001    // RelativeTime.java, created by cata
002    // Copyright (C) 2001 Catalin Francu <cata@mit.edu>
003    //    taking over Bryan Fink's code
004    // Licensed under the terms of the GNU GPL; see COPYING for details.
005    
006    package javax.realtime;
007    
008    import java.util.Date;
009    
010    /** An object that represents a time interval millis/1E3+nanos/1E9
011     *  seconds long. It generally is used to represent a time relative
012     *  to now.
013     *  <p>
014     *  If the values of any of the millisecond or nanosecond fields is
015     *  negative the variable is set to negative value. Although logically,
016     *  and correctly, this may represent time before the epoch, invalid
017     *  results <i>may</i> occur if an instance of <code>RelativeTime</code>
018     *  representing time before the epoch is given as a paramter to some
019     *  method. For <code>add</code> and <code>subtract</code> negative values
020     *  behave just like they do in arithmetic.
021     *  <p>
022     *  <b>Caution:</b> This class is explicitly unsafe in multithreaded
023     *  situations when it is being changed. No synchronization is done. It is
024     *  assumed that users of this class who are mutating instances will be
025     *  doing their own synchronization at a higher level
026     */
027    public class RelativeTime extends HighResolutionTime {
028        
029        public static RelativeTime ZERO = new RelativeTime(0, 0);
030        
031        /** Equivalent to <code>new RelativeTime(0, 0)</code>. */
032        public RelativeTime() {
033            this(0, 0);
034        }
035    
036        /** Constructs a <code>RelativeTime</code> object representing an interval
037         *  defined by the given parameter values.
038         *
039         *  @param millis The milliseconds component.
040         *  @param nanos The nanoseconds component.
041         */
042        public RelativeTime(long millis, int nanos) {
043            set(millis, nanos);
044        }
045        
046        /** Make a new <code>RelativeTime</code> object from the given
047         *  <code>RelativeTime</code> object.
048         *
049         *  @param t The <code>RelativeTime</code> object used as the source
050         *           for the copy.
051         */
052        public RelativeTime(RelativeTime t) {
053            this(t.getMilliseconds(), t.getNanoseconds());
054        }
055    
056        /** Convert the time given by <code>this</code> to an absolute time. The
057         *  calculation is the current time indicated by the given instance of
058         *  <code>Clock</code> plus the interval given by <code>this</code>.
059         *
060         *  @param clock The given instance of <code>Clock</code> If null,
061         *               <code>Clock.getRealTimeClock()</code> is used.
062         *  @return The new instance of <code>AbsoluteTime</code> containing the result.
063         */
064        public AbsoluteTime absolute(Clock clock) {
065            return new AbsoluteTime(clock.getTime().add(this));
066        }
067    
068        /** Convert the time given by <code>this</code> to an absolute time. The
069         *  calculation is the current time indicated by the given instance of
070         *  <code>Clock</code> plus the interval given by <code>this</code>.
071         *
072         *  @param clock The given instance of <code>Clock</code> If null,
073         *               <code>Clock.getRealTimeClock()</code> is used.
074         *  @param destination A reference to the result instance of
075         *                     <code>AbsoluteTime</code>.
076         *  @return The new instance of <code>AbsoluteTime</code> containing the result.
077         */
078        public AbsoluteTime absolute(Clock clock, AbsoluteTime destination) {
079            if (destination == null)
080                destination = new AbsoluteTime();
081            if (clock == null)
082                clock = Clock.getRealtimeClock();
083            
084            destination.set(clock.getTime().add(this));
085            return destination;
086        }
087    
088        /** Add a specific number of milliseconds and nanoseconds to the appropriate
089         *  fields of <code>this</code>. A new object is allocated.
090         *
091         *  @param millis The number of milliseconds to add.
092         *  @param nanos The number of nanoseconds to add.
093         *  @return A new object containing the result of the addition.
094         */
095        public RelativeTime add(long millis, int nanos) {
096            return new RelativeTime(getMilliseconds() + millis,
097                                    getNanoseconds() + nanos);
098        }
099    
100        /** Add a specific number of milliseconds and nanoseconds to the appropriate
101         *  fields of <code>this</code>. A new object is allocated.
102         *
103         *  @param millis The number of milliseconds to add.
104         *  @param nanos The number of nanoseconds to add.
105         *  @param destination A reference to the result instance of
106         *                     <code>RelativeTime</code>.
107         *  @return A new object containing the result of the addition
108         */
109        public RelativeTime add(long millis, int nanos, RelativeTime destination) {
110            if (destination == null)
111                destination = new RelativeTime();
112            
113            destination.set(getMilliseconds() + millis,
114                            getNanoseconds() + nanos);
115            return destination;
116        }
117        
118        /** Add the interval of <code>this</code> to the interval of the given
119         *  instance of <code>RelativeTime</code>.
120         *
121         *  @param time A reference to the given instance of <code>RelativeTime</code>.
122         *  @return A new object containing the result of the addition.
123         */
124        public final RelativeTime add(RelativeTime time) {
125            return new RelativeTime(getMilliseconds() + time.getMilliseconds(),
126                                    getNanoseconds() + time.getNanoseconds());
127        }
128    
129        /** Add the interval of <code>this</code> to the interval of the given
130         *  instance of <code>RelativeTime</code>.
131         *
132         *  @param time A reference to the given instance of <code>RelativeTime</code>.
133         *  @param destination A reference to the result instance of <code>RelativeTime</code>.
134         *  @return A new object containing the result of the addition.
135         */
136        public RelativeTime add(RelativeTime time, RelativeTime destination) {
137            if (destination == null)
138                destination = new RelativeTime();
139            
140            destination.set(getMilliseconds() + time.getMilliseconds(),
141                            getNanoseconds() + time.getNanoseconds());
142            return destination;
143        }
144        
145        /** Add the interval of <code>this</code> to the given instance of
146         *  <code>AbsoluteTime</code>.
147         *
148         *  @param destination A reference to the given instance of
149         *                     <code>AbsoluteTime</code> and the result.
150         */
151        public void addInterarrivalTo(AbsoluteTime destination) {
152            try {
153                destination.add(this, destination);
154            } catch (NullPointerException e) {
155                System.out.println("A NullPointerException occured in " +
156                                   "RelativeTime.addInterarrivalTo(AbsoluteTime destination)");
157            }
158        }
159    
160        /** Gets the interval defined by <code>this</code>. For an instance of
161         *  <code>RationalTime</code> it is the interval divided by the frequency.
162         *
163         *  @return A reference to a new instance of <code>RelativeTime</code>
164         *          with the same interval as <code>this</code>.
165         */
166        public RelativeTime getInterarrivalTime() {
167            return new RelativeTime(this);
168        }
169    
170        /** Gets the interval defined by <code>this</code> For an instance of
171         *  <code>RelativeTime</code> it is the interval divided by the frequency.
172         *
173         *  @param destination A reference to the new object holding the result.
174         *  @return A reference to an object holding the result.
175         */
176        public RelativeTime getInterarrivalTime(RelativeTime destination) {
177            destination = new RelativeTime(this);
178            return destination;
179        }
180        
181        /** Make a new <code>RelativeTime</code> object from the time given by
182         *  <code>this</code> but based on the given instance of <code>Clock</code>.
183         *
184         *  @param clock The given instance of <code>Clock</code>.
185         *  @return A reference to the new instance of <code>RelativeTime</code>.
186         */
187        public RelativeTime relative(Clock clock) {
188            set(getMilliseconds() +
189                defaultClock.getTime().getMilliseconds() -
190                clock.getTime().getMilliseconds(),
191                getNanoseconds() +
192                defaultClock.getTime().getNanoseconds() -
193                clock.getTime().getNanoseconds());
194            return this;
195        }
196    
197        /** Make a new <code>RelativeTime</code> object from the time given by
198         *  <code>this</code> but based on the given instance of <code>Clock</code>.
199         *
200         *  @param clock The given instance of <code>Clock</code>.
201         *  @param time A reference to the result instance of <code>RelativeTime</code>.
202         *  @return A reference to the new instance of <code>RelativeTime</code>.
203         */
204        public RelativeTime relative(Clock clock, RelativeTime time) {
205            set(time.getMilliseconds() +
206                defaultClock.getTime().getMilliseconds() -
207                clock.getTime().getMilliseconds(),
208                time.getNanoseconds() +
209                defaultClock.getTime().getNanoseconds() -
210                clock.getTime().getNanoseconds());
211            return this;
212        }
213    
214        /** Make a new <code>RelativeTime</code> object from the time given by
215         *  <code>this</code> but based on the given instance of <code>Clock</code>.
216         *
217         *  @param clock The given instance of <code>Clock</code>.
218         *  @param time A reference to the result instance of <code>RelativeTime</code>.
219         *  @return A reference to the new instance of <code>HighResolutionTime</code>.
220         */
221        public RelativeTime relative(Clock clock, HighResolutionTime time) {
222            set(time.getMilliseconds() +
223                defaultClock.getTime().getMilliseconds() -
224                clock.getTime().getMilliseconds(),
225                time.getNanoseconds() +
226                defaultClock.getTime().getNanoseconds() -
227                clock.getTime().getNanoseconds());
228            return this;
229        }
230        
231        /** Subtract the interval defined by the given instance of
232         *  <code>RelativeTime</code> from the interval defined by <code>this</code>.
233         *
234         *  @param time A reference to the given instance of <code>RelativeTime</code>.
235         *  @return A new object holding the result of the subtraction.
236         */
237        public final RelativeTime subtract(RelativeTime time) {
238            return new RelativeTime(getMilliseconds() - time.getMilliseconds(),
239                                    getNanoseconds() - time.getNanoseconds());
240        }
241        
242        /** Subtract the interval defined by the given instance of
243         *  <code>RelativeTime</code> from the interval defined by <code>this</code>.
244         *
245         *  @param time A reference to the given instance of <code>RelativeTime</code>.
246         *  @param destination A reference to the object holding the result.
247         *  @return A new object holding the result of the subtraction.
248         */
249        public RelativeTime subtract(RelativeTime time, RelativeTime destination) {
250            if (destination == null)
251                destination = new RelativeTime();
252            
253            destination.set(getMilliseconds() - time.getMilliseconds(),
254                            getNanoseconds() - time.getNanoseconds());
255            return destination;
256        }
257        
258        /** Return a printable version of the time defined by <code>this</code>.
259         *
260         *  @return An instance of <code>java.lang.String</code> representing the
261         *          time defined by <code>this</code>.
262         */
263        public String toString() {
264            return "RelativeTime: millis: " + getMilliseconds() +
265                " nanos: " + getNanoseconds();
266        }
267    }