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 specific point in time given by
011     *  milliseconds plus nanoseconds past the epoch (Jenuary 1, 1970,
012     *  00:00:00 GMT). This representation was designed to be compatible
013     *  with the standard Java representation of an absolute time in the
014     *  <code>java.util.Date</code> class.
015     *  <p>
016     *  If the value of any of the millisecond or nanosecond fields is negative
017     *  the variable is set to negative value. Although logically this may
018     *  represent time before the epoch, invalid results may occur if an instance
019     *  of <code>AbsoluteTime</code> representing time before the epoch is given
020     *  as a parameter to a method. For <code>add</code> and <code>subtract</code>
021     *  negative values behave just like they do in arithmetic.
022     *  <p>
023     *  <b>Caution:</b> This class is explicitly unsafe in multithreaded situations
024     *  when it is being changed. No synchronization is done. It is assumed that
025     *  users of this class who are mutating instances will be doing their own
026     *  synchronization at a higher level.
027     */
028    public class AbsoluteTime extends HighResolutionTime {
029        
030        public static AbsoluteTime endOfDays =
031            new AbsoluteTime(Long.MAX_VALUE, 0);
032        
033        /** Equal to new <code>AbsoluteTime(0,0)</code>. */
034        public AbsoluteTime()       {
035            this(0, 0);
036        }
037     
038        /** Make a new <code>AbsoluteTime</code> object from the given
039         *  <code>AbsoluteTime</code> object.
040         *
041         *  @param time The <code>AbsoluteTime</code> object which is the source
042         *              for the copy.
043         */
044        public AbsoluteTime(AbsoluteTime t) {
045            this(t.getMilliseconds(), t.getNanoseconds());
046        }
047    
048        /** Equivalent to <code>new AbsoluteTime(date.getTime(), 0)</code>.
049         *
050         *  @param date The <code>java.util.Date</code> representation of the time
051         *              past the epoch.
052         */
053        public AbsoluteTime(Date date) {
054            this(date.getTime(), 0);
055        }
056    
057        /** Construct an <code>AbsoluteTime</code> object which means a time
058         *  <code>millis</code> milliseconds plus <code>nanos</code> nanoseconds
059         *  past 00:00:00 GMT on January 1, 1970.
060         *
061         *  @param millis The milliseconds component of the time past the epoch.
062         *  @param nanos The nanosecond component of the time past the epoch.
063         */
064        public AbsoluteTime(long millis, int nanos) {
065            super();
066            set(millis, nanos);
067        }
068        
069        /** Convert time given by <code>this</code> to an absolute time relative
070         *  to a given clock.
071         *
072         *  @param clock The clock on which <code>this</code> will be based.
073         *  @return A reference to <code>this</code>.
074         */
075        public AbsoluteTime absolute(Clock clock) {
076            AbsoluteTime tempTime = clock.getTime();
077            long tempMillis = getMilliseconds() - tempTime.getMilliseconds();
078            int tempNanos = getNanoseconds() - tempTime.getNanoseconds();
079            if (tempNanos < 0) {
080                tempMillis--;
081                tempNanos += 1000000;
082            }
083            set(tempMillis, tempNanos);
084    
085            return this;
086        }
087        
088        /** Convert this time to an absolute time. For an <code>AbsoluteTime</code>,
089         *  this is really easy: it just return itself. Presumes that this is already
090         *  relative to the given clock.
091         *
092         *  @param clock The clock on which this is based.
093         *  @param destination Converted to an absolute time.
094         *  @return A reference to <code>this</code>.
095         */
096        public AbsoluteTime absolute(Clock clock, AbsoluteTime destination) {
097            if (destination != null)
098                destination.set(this);
099            return this;
100        }
101        
102        /** Add <code>millis</code> and <code>nanos</code> to <code>this</code>. A new
103         *  object is allocated for the result.
104         *
105         *  @param millis The number of milliseconds to be added to <code>this</code>.
106         *  @param nanos The number of nanoseconds to be added to <code>this</code>.
107         *  @return A new <code>AbsoluteTime</code> object whose time is <code>this</code>
108         *          plus <code>millis</code> and <code>nanos</code>.
109         */
110        public AbsoluteTime add(long millis, int nanos) {
111            return new AbsoluteTime(getMilliseconds() + millis,
112                                    getNanoseconds() + nanos);
113        }
114    
115        /** Add <code>millis</code> and <code>nanos</code> to <code>this</code>. If the
116         *  <code>destination</code> is non-null, the result is placed there and returned.
117         *  Otherwise, a new object is allocated for the result.
118         *
119         *  @param millis The number of milliseconds to be added to <code>this</code>.
120         *  @param nanos The number of nanoseconds to be added to <code>this</code>.
121         *  @param destination A reference to an <code>AbsoluteTime</code> object into
122         *                     which the result of the addition may be placed.
123         */
124        public AbsoluteTime add(long millis, int nanos, AbsoluteTime destination) {
125            if (destination == null)
126                destination = new AbsoluteTime();
127            
128            destination.set(getMilliseconds() + millis,
129                            getNanoseconds() + nanos);
130            return destination;
131        }
132        
133        /** Add the time given by the parameter to <code>this</code>.
134         *
135         *  @param time The time to add to <code>this</code>.
136         *  @return A reference to <code>this</code>.
137         */
138        public final AbsoluteTime add(RelativeTime time) {
139            return new AbsoluteTime(getMilliseconds() + time.getMilliseconds(),
140                                    getNanoseconds() + time.getNanoseconds());
141        }
142    
143        /** Add the time given by the parameter to <code>this</code>. If the
144         *  <code>destination</code> is non-null, the result is placed there
145         *  and returned. Otherwise, a new object is allocated for the result.
146         *
147         *  @param time The time to add to <code>this</code>.
148         *  @param destination A reference to an <code>AbsoluteTime</code> object
149         *                     into which the result of the addition may be placed.
150         *  @return A reference to <code>destination</code> or a new object whose
151         *          time is <code>this</code> plus <code>millis</codeN and <code>nano</code>.
152         */
153        public AbsoluteTime add(RelativeTime time, AbsoluteTime destination) {
154            if (destination == null)
155                destination = new AbsoluteTime();
156            
157            destination.set(getMilliseconds() + time.getMilliseconds(),
158                            getNanoseconds() + time.getNanoseconds());
159            return destination;
160        }
161        
162        /** Convert the time given by <code>this</code> to a <code>java.utilDate</code>
163         *  format. Note that <code>java.util.Date</code> represents time as milliseconds
164         *  so the nanoseconds of <code>this</code> will be lost.
165         *
166         *  @return A reference to a <code>java.util.Date</code> object with a value of
167         *          the time past the epoch represented by <code>this</code>.
168         */
169        public Date getDate() {
170            return new Date(getMilliseconds());
171        }
172    
173        /** Create a <code>RelativeTime</code> object with current time given by
174         *  <code>this</code> with reference to the parameter.
175         *
176         *  @param clock The clock reference used as a reference for this.
177         *  @return A reference to a new <code>RelativeTime</code> object whose time is
178         *          set to the time given by <code>this</code> referencing the parameter.
179         */
180        public RelativeTime relative(Clock clock) {
181            return new RelativeTime(getMilliseconds() -
182                                    clock.getTime().getMilliseconds(),
183                                    getNanoseconds() - 
184                                    clock.getTime().getNanoseconds());
185        }
186    
187        /** Create a <code>RelativeTime</code> object with current time given by
188         *  <code>this</code> with reference to <code>Clock</code> parameter. If the
189         *  <code>destination</code> is non-null, the result is placed there and
190         *  returned. Otherwise, a new object is allocated for the result
191         *
192         *  @param clock The clock reference used as a reference for this.
193         *  @param destination A reference to a <code>RelativeTime</code> object into
194         *                     which the result of the subtraction may be placed.
195         *  @return A reference to a new <code>RelativeTime</code> object whose time is
196         *          set to the time given by <code>this</code> referencing the parameter.
197         */
198        public RelativeTime relative(Clock clock, AbsoluteTime destination) {
199            return new RelativeTime(destination.getMilliseconds() -
200                                    clock.getTime().getMilliseconds(),
201                                    destination.getNanoseconds() -
202                                    clock.getTime().getNanoseconds());
203        }
204        
205        /** Create a <code>RelativeTime</code> object with current time given by
206         *  <code>this</code> with reference to <code>Clock</code> parameter. If the
207         *  <code>destination</code> is non-null, the result is placed there and
208         *  returned. Otherwise, a new object is allocated for the result
209         *
210         *  @param clock The clock reference used as a reference for this.
211         *  @param time A reference to a <code>HighResolutionTime</code> object into
212         *              which the result of the subtraction may be placed.
213         *  @return A reference to a new <code>RelativeTime</code> object whose time is
214         *          set to the time given by <code>this</code> referencing the parameter.
215         */
216        public RelativeTime relative(Clock clock, HighResolutionTime time) {
217            return new RelativeTime(time.getMilliseconds() -
218                                    clock.getTime().getMilliseconds(),
219                                    time.getNanoseconds() -
220                                    clock.getTime().getNanoseconds());
221        }
222    
223        /** Change the time represented by <code>this</code> to that given by the parameter.
224         *
225         *  @param date A reference to a <code>java.util.Date</code> which will become the
226         *              time represented by <code>this</code> after the completion of this method.
227         */
228        public void set(Date d) {
229            set(d.getTime());
230        }
231    
232        /** Finds the difference between the time given by <code>this</code> and the time
233         *  given by the parameter. The difference is, of course, a <code>RelativeTime</code>.
234         *
235         *  @param time A reference to an <code>AbsoluteTime</code> object whose time is
236         *              subtracted from <code>this</code>.
237         *  @return A reference to a new <code>RelativeTime</code> object whose time is the
238         *          difference.
239         */
240        public final RelativeTime subtract(AbsoluteTime time) {
241            return new RelativeTime(getMilliseconds() - time.getMilliseconds(),
242                                    getNanoseconds() - time.getNanoseconds());
243        }
244    
245        /** Finds the difference between the time given by <code>this</code> and the time
246         *  given by the parameter. The difference is, of course, a <code>RelativeTime</code>.
247         *  If the <code>destination</code> is non-null, the result is placed there and
248         *  returned. Otherwise, a new object is allocated for the result.
249         *
250         *  @param time A reference to an <code>AbsoluteTime</code> object whose time is
251         *              subtracted from <code>this</code>.
252         *  @param destination A reference to an <code>RelativeTime</code> object into which
253         *                     the result of the addition may be placed.
254         *  @return A reference to a new <code>RelativeTime</code> object whose time is the
255         *          difference between <code>this</code> and the <code>time</code> paramter.
256         */
257        public RelativeTime subtract(AbsoluteTime time, RelativeTime destination) {
258            if (destination == null)
259                destination = new RelativeTime();
260            
261            destination.set(getMilliseconds() - time.getMilliseconds(),
262                            getNanoseconds() - time.getNanoseconds());
263            return destination;
264        }
265    
266        /** Finds the difference between the time given by <code>this</code> and the time
267         *  given by the parameter.
268         *
269         *  @param time A reference to an <code>AbsoluteTime</code> object whose time is
270         *              subtracted from <code>this</code>.
271         *  @return A reference to a new <code>AbsoluteTime</code> object whose time is the
272         *          difference.
273         */
274        public final AbsoluteTime subtract(RelativeTime time) {
275            return new AbsoluteTime(getMilliseconds() - time.getMilliseconds(),
276                                    getNanoseconds() - time.getNanoseconds());
277        }
278    
279        /** Finds the difference between the time given by <code>this</code> and the time
280         *  given by the parameter. The difference is, of course, a <code>RelativeTime</code>.
281         *  If the <code>destination</code> is non-null, the result is placed there and
282         *  returned. Otherwise, a new object is allocated for the result.
283         *
284         *  @param time A reference to an <code>AbsoluteTime</code> object whose time is
285         *              subtracted from <code>this</code>.
286         *  @param destination A reference to an <code>AbsoluteTime</code> object into which
287         *                     the result of the addition may be placed.
288         *  @return A reference to a new <code>AbsoluteTime</code> object whose time is the
289         *          difference between <code>this</code> and <code>time</code> parameter.
290         */
291        public AbsoluteTime subtract(RelativeTime time, AbsoluteTime destination) {
292            if (destination == null)
293                destination = new AbsoluteTime();
294            
295            destination.set(getMilliseconds() - time.getMilliseconds(),
296                            getNanoseconds() - time.getNanoseconds());
297            return destination;
298        }
299        
300        /** Create a printable string of the time given by <code>this</code>, in a format
301         *  that matches <code>java.util.Date.toString()</code> with a postfix to the
302         *  detail the nanosecond value.
303         *
304         *  @return String object converted from the time given ty <code>this</code>.
305         */
306        public String toString() {
307            Date result = new Date();
308            result.setTime(getMilliseconds());
309            
310            return "AbsoluteTime: " + result.toString() + " millis: " +
311                getMilliseconds()%1000 + " nanos: " + getNanoseconds();
312        }
313    }