001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2022, by David Gilbert and Contributors.
006 *
007 * Project Info:  http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022 * USA.
023 *
024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * ---------------------
028 * FixedMillisecond.java
029 * ---------------------
030 * (C) Copyright 2002-2022, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   Ulrich Voigt;
034 *
035 */
036
037package org.jfree.data.time;
038
039import java.io.Serializable;
040import java.util.Calendar;
041import java.util.Date;
042
043/**
044 * Wrapper for a {@code java.util.Date} object that allows it to be used
045 * as a {@link RegularTimePeriod}.  This class is immutable, which is a
046 * requirement for all {@link RegularTimePeriod} subclasses.
047 */
048public class FixedMillisecond extends RegularTimePeriod
049        implements Serializable {
050
051    /** For serialization. */
052    private static final long serialVersionUID = 7867521484545646931L;
053
054    /** The millisecond. */
055    private final long time;
056
057    /**
058     * Constructs a millisecond based on the current system time.
059     */
060    public FixedMillisecond() {
061        this(System.currentTimeMillis());
062    }
063
064    /**
065     * Constructs a millisecond.
066     *
067     * @param millisecond  the millisecond (same encoding as java.util.Date).
068     */
069    public FixedMillisecond(long millisecond) {
070        this.time = millisecond;
071    }
072
073    /**
074     * Constructs a millisecond.
075     *
076     * @param time  the time ({@code null} not permitted).
077     */
078    public FixedMillisecond(Date time) {
079        this(time.getTime());
080    }
081
082    /**
083     * Returns the date/time (creates a new {@code Date} instance each time 
084     * this method is called).
085     *
086     * @return The date/time.
087     */
088    public Date getTime() {
089        return new Date(this.time);
090    }
091
092    /**
093     * This method is overridden to do nothing.
094     *
095     * @param calendar  ignored
096     *
097     * @since 1.0.3
098     */
099    @Override
100    public void peg(Calendar calendar) {
101        // nothing to do
102    }
103
104    /**
105     * Returns the millisecond preceding this one.
106     *
107     * @return The millisecond preceding this one.
108     */
109    @Override
110    public RegularTimePeriod previous() {
111        RegularTimePeriod result = null;
112        long t = this.time;
113        if (t != Long.MIN_VALUE) {
114            result = new FixedMillisecond(t - 1);
115        }
116        return result;
117    }
118
119    /**
120     * Returns the millisecond following this one.
121     *
122     * @return The millisecond following this one.
123     */
124    @Override
125    public RegularTimePeriod next() {
126        RegularTimePeriod result = null;
127        long t = this.time;
128        if (t != Long.MAX_VALUE) {
129            result = new FixedMillisecond(t + 1);
130        }
131        return result;
132    }
133
134    /**
135     * Tests the equality of this object against an arbitrary Object.
136     *
137     * @param object  the object to compare
138     *
139     * @return A boolean.
140     */
141    @Override
142    public boolean equals(Object object) {
143        if (object instanceof FixedMillisecond) {
144            FixedMillisecond m = (FixedMillisecond) object;
145            return this.time == m.getFirstMillisecond();
146        }
147        else {
148            return false;
149        }
150
151    }
152
153    /**
154     * Returns a hash code for this object instance.
155     *
156     * @return A hash code.
157     */
158    @Override
159    public int hashCode() {
160        return (int) this.time;
161    }
162
163    /**
164     * Returns an integer indicating the order of this Millisecond object
165     * relative to the specified
166     * object: negative == before, zero == same, positive == after.
167     *
168     * @param o1    the object to compare.
169     *
170     * @return negative == before, zero == same, positive == after.
171     */
172    @Override
173    public int compareTo(Object o1) {
174
175        int result;
176        long difference;
177
178        // CASE 1 : Comparing to another Second object
179        // -------------------------------------------
180        if (o1 instanceof FixedMillisecond) {
181            FixedMillisecond t1 = (FixedMillisecond) o1;
182            difference = this.time - t1.time;
183            if (difference > 0) {
184                result = 1;
185            }
186            else {
187                if (difference < 0) {
188                   result = -1;
189                }
190                else {
191                    result = 0;
192                }
193            }
194        }
195
196        // CASE 2 : Comparing to another TimePeriod object
197        // -----------------------------------------------
198        else if (o1 instanceof RegularTimePeriod) {
199            // more difficult case - evaluate later...
200            result = 0;
201        }
202
203        // CASE 3 : Comparing to a non-TimePeriod object
204        // ---------------------------------------------
205        else {
206            // consider time periods to be ordered after general objects
207            result = 1;
208        }
209
210        return result;
211
212    }
213
214    /**
215     * Returns the first millisecond of the time period.
216     *
217     * @return The first millisecond of the time period.
218     */
219    @Override
220    public long getFirstMillisecond() {
221        return this.time;
222    }
223
224
225    /**
226     * Returns the first millisecond of the time period.
227     *
228     * @param calendar  the calendar.
229     *
230     * @return The first millisecond of the time period.
231     */
232    @Override
233    public long getFirstMillisecond(Calendar calendar) {
234        return this.time;
235    }
236
237    /**
238     * Returns the last millisecond of the time period.
239     *
240     * @return The last millisecond of the time period.
241     */
242    @Override
243    public long getLastMillisecond() {
244        return this.time;
245    }
246
247    /**
248     * Returns the last millisecond of the time period.
249     *
250     * @param calendar  the calendar.
251     *
252     * @return The last millisecond of the time period.
253     */
254    @Override
255    public long getLastMillisecond(Calendar calendar) {
256        return this.time;
257    }
258
259    /**
260     * Returns the millisecond closest to the middle of the time period.
261     *
262     * @return The millisecond closest to the middle of the time period.
263     */
264    @Override
265    public long getMiddleMillisecond() {
266        return this.time;
267    }
268
269    /**
270     * Returns the millisecond closest to the middle of the time period.
271     *
272     * @param calendar  the calendar.
273     *
274     * @return The millisecond closest to the middle of the time period.
275     */
276    @Override
277    public long getMiddleMillisecond(Calendar calendar) {
278        return this.time;
279    }
280
281    /**
282     * Returns a serial index number for the millisecond.
283     *
284     * @return The serial index number.
285     */
286    @Override
287    public long getSerialIndex() {
288        return this.time;
289    }
290
291}