View Javadoc

1   /*
2    *  Copyright 2001-2010 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time;
17  
18  import java.io.Serializable;
19  
20  import org.joda.convert.FromString;
21  import org.joda.time.base.AbstractInstant;
22  import org.joda.time.chrono.ISOChronology;
23  import org.joda.time.convert.ConverterManager;
24  import org.joda.time.convert.InstantConverter;
25  import org.joda.time.format.DateTimeFormatter;
26  import org.joda.time.format.ISODateTimeFormat;
27  
28  /**
29   * Instant is the standard implementation of a fully immutable instant in time.
30   * <p>
31   * <code>Instant</code> is an implementation of {@link ReadableInstant}.
32   * As with all instants, it represents an exact point on the time-line,
33   * but limited to the precision of milliseconds. An <code>Instant</code>
34   * should be used to represent a point in time irrespective of any other
35   * factor, such as chronology or time zone.
36   * <p>
37   * Internally, the class holds one piece of data, the instant as milliseconds
38   * from the Java epoch of 1970-01-01T00:00:00Z.
39   * <p>
40   * For example, an Instant can be used to compare two <code>DateTime</code>
41   * objects irrespective of chronology or time zone.
42   * <pre>
43   * boolean sameInstant = dt1.toInstant().equals(dt2.toInstant());
44   * </pre>
45   * Note that the following code will also perform the same check:
46   * <pre>
47   * boolean sameInstant = dt1.isEqual(dt2);
48   * </pre>
49   * <p>
50   * Instant is thread-safe and immutable.
51   *
52   * @author Stephen Colebourne
53   * @since 1.0
54   */
55  public final class Instant
56          extends AbstractInstant
57          implements ReadableInstant, Serializable {
58  
59      /** Serialization lock */
60      private static final long serialVersionUID = 3299096530934209741L;
61  
62      /** The millis from 1970-01-01T00:00:00Z */
63      private final long iMillis;
64  
65      //-----------------------------------------------------------------------
66      /**
67       * Obtains an {@code Instant} set to the current system millisecond time.
68       * 
69       * @return the current instant, not null
70       * @since 2.0
71       */
72      public static Instant now() {
73          return new Instant();
74      }
75  
76      //-----------------------------------------------------------------------
77      /**
78       * Parses a {@code Instant} from the specified string.
79       * <p>
80       * This uses {@link ISODateTimeFormat#dateTimeParser()}.
81       * 
82       * @param str  the string to parse, not null
83       * @since 2.0
84       */
85      @FromString
86      public static Instant parse(String str) {
87          return parse(str, ISODateTimeFormat.dateTimeParser());
88      }
89  
90      /**
91       * Parses a {@code Instant} from the specified string using a formatter.
92       * 
93       * @param str  the string to parse, not null
94       * @param formatter  the formatter to use, not null
95       * @since 2.0
96       */
97      public static Instant parse(String str, DateTimeFormatter formatter) {
98          return formatter.parseDateTime(str).toInstant();
99      }
100 
101     //-----------------------------------------------------------------------
102     /**
103      * Constructs an instance set to the current system millisecond time.
104      * 
105      * @see #now()
106      */
107     public Instant() {
108         super();
109         iMillis = DateTimeUtils.currentTimeMillis();
110     }
111 
112     /**
113      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z.
114      * 
115      * @param instant  the milliseconds from 1970-01-01T00:00:00Z
116      */
117     public Instant(long instant) {
118         super();
119         iMillis = instant;
120     }
121 
122     /**
123      * Constructs an instance from an Object that represents a datetime.
124      * <p>
125      * The recognised object types are defined in {@link ConverterManager} and
126      * include String, Calendar and Date.
127      *
128      * @param instant  the datetime object, null means now
129      * @throws IllegalArgumentException if the instant is invalid
130      */
131     public Instant(Object instant) {
132         super();
133         InstantConverter converter = ConverterManager.getInstance().getInstantConverter(instant);
134         iMillis = converter.getInstantMillis(instant, ISOChronology.getInstanceUTC());
135     }
136 
137     //-----------------------------------------------------------------------
138     /**
139      * Get this object as an Instant by returning <code>this</code>.
140      * 
141      * @return <code>this</code>
142      */
143     public Instant toInstant() {
144         return this;
145     }
146 
147     //-----------------------------------------------------------------------
148     /**
149      * Gets a copy of this instant with different millis.
150      * <p>
151      * The returned object will be either be a new Instant or <code>this</code>.
152      *
153      * @param newMillis  the new millis, from 1970-01-01T00:00:00Z
154      * @return a copy of this instant with different millis
155      */
156     public Instant withMillis(long newMillis) {
157         return (newMillis == iMillis ? this : new Instant(newMillis));
158     }
159 
160     /**
161      * Gets a copy of this instant with the specified duration added.
162      * <p>
163      * If the addition is zero, then <code>this</code> is returned.
164      * 
165      * @param durationToAdd  the duration to add to this one
166      * @param scalar  the amount of times to add, such as -1 to subtract once
167      * @return a copy of this instant with the duration added
168      * @throws ArithmeticException if the new instant exceeds the capacity of a long
169      */
170     public Instant withDurationAdded(long durationToAdd, int scalar) {
171         if (durationToAdd == 0 || scalar == 0) {
172             return this;
173         }
174         long instant = getChronology().add(getMillis(), durationToAdd, scalar);
175         return withMillis(instant);
176     }
177 
178     /**
179      * Gets a copy of this instant with the specified duration added.
180      * <p>
181      * If the addition is zero, then <code>this</code> is returned.
182      * 
183      * @param durationToAdd  the duration to add to this one, null means zero
184      * @param scalar  the amount of times to add, such as -1 to subtract once
185      * @return a copy of this instant with the duration added
186      * @throws ArithmeticException if the new instant exceeds the capacity of a long
187      */
188     public Instant withDurationAdded(ReadableDuration durationToAdd, int scalar) {
189         if (durationToAdd == null || scalar == 0) {
190             return this;
191         }
192         return withDurationAdded(durationToAdd.getMillis(), scalar);
193     }
194 
195     //-----------------------------------------------------------------------
196     /**
197      * Gets a copy of this instant with the specified duration added.
198      * <p>
199      * If the amount is zero or null, then <code>this</code> is returned.
200      * 
201      * @param duration  the duration to add to this one
202      * @return a copy of this instant with the duration added
203      * @throws ArithmeticException if the new instant exceeds the capacity of a long
204      */
205     public Instant plus(long duration) {
206         return withDurationAdded(duration, 1);
207     }
208 
209     /**
210      * Gets a copy of this instant with the specified duration added.
211      * <p>
212      * If the amount is zero or null, then <code>this</code> is returned.
213      * 
214      * @param duration  the duration to add to this one, null means zero
215      * @return a copy of this instant with the duration added
216      * @throws ArithmeticException if the new instant exceeds the capacity of a long
217      */
218     public Instant plus(ReadableDuration duration) {
219         return withDurationAdded(duration, 1);
220     }
221 
222     //-----------------------------------------------------------------------
223     /**
224      * Gets a copy of this instant with the specified duration taken away.
225      * <p>
226      * If the amount is zero or null, then <code>this</code> is returned.
227      * 
228      * @param duration  the duration to reduce this instant by
229      * @return a copy of this instant with the duration taken away
230      * @throws ArithmeticException if the new instant exceeds the capacity of a long
231      */
232     public Instant minus(long duration) {
233         return withDurationAdded(duration, -1);
234     }
235 
236     /**
237      * Gets a copy of this instant with the specified duration taken away.
238      * <p>
239      * If the amount is zero or null, then <code>this</code> is returned.
240      * 
241      * @param duration  the duration to reduce this instant by
242      * @return a copy of this instant with the duration taken away
243      * @throws ArithmeticException if the new instant exceeds the capacity of a long
244      */
245     public Instant minus(ReadableDuration duration) {
246         return withDurationAdded(duration, -1);
247     }
248 
249     //-----------------------------------------------------------------------
250     /**
251      * Gets the milliseconds of the instant.
252      * 
253      * @return the number of milliseconds since 1970-01-01T00:00:00Z
254      */
255     public long getMillis() {
256         return iMillis;
257     }
258 
259     /**
260      * Gets the chronology of the instant, which is ISO in the UTC zone.
261      * <p>
262      * This method returns {@link ISOChronology#getInstanceUTC()} which
263      * corresponds to the definition of the Java epoch 1970-01-01T00:00:00Z.
264      * 
265      * @return ISO in the UTC zone
266      */
267     public Chronology getChronology() {
268         return ISOChronology.getInstanceUTC();
269     }
270 
271     //-----------------------------------------------------------------------
272     /**
273      * Get this object as a DateTime using ISOChronology in the default zone.
274      * <p>
275      * This method returns a DateTime object in the default zone.
276      * This differs from the similarly named method on DateTime, DateMidnight
277      * or MutableDateTime which retains the time zone. The difference is
278      * because Instant really represents a time <i>without</i> a zone,
279      * thus calling this method we really have no zone to 'retain' and
280      * hence expect to switch to the default zone.
281      * <p>
282      * This method definition preserves compatibility with earlier versions
283      * of Joda-Time.
284      *
285      * @return a DateTime using the same millis
286      */
287     public DateTime toDateTime() {
288         return new DateTime(getMillis(), ISOChronology.getInstance());
289     }
290 
291     /**
292      * Get this object as a DateTime using ISOChronology in the default zone.
293      * This method is identical to <code>toDateTime()</code>.
294      * <p>
295      * This method returns a DateTime object in the default zone.
296      * This differs from the similarly named method on DateTime, DateMidnight
297      * or MutableDateTime which retains the time zone. The difference is
298      * because Instant really represents a time <i>without</i> a zone,
299      * thus calling this method we really have no zone to 'retain' and
300      * hence expect to switch to the default zone.
301      * <p>
302      * This method is deprecated because it is a duplicate of {@link #toDateTime()}.
303      * However, removing it would cause the superclass implementation to be used,
304      * which would create silent bugs in any caller depending on this implementation.
305      * As such, the method itself is not currently planned to be removed.
306      * <p>
307      * This method definition preserves compatibility with earlier versions
308      * of Joda-Time.
309      *
310      * @return a DateTime using the same millis with ISOChronology
311      * @deprecated Use toDateTime() as it is identical
312      */
313     @Deprecated
314     public DateTime toDateTimeISO() {
315         return toDateTime();
316     }
317 
318     /**
319      * Get this object as a MutableDateTime using ISOChronology in the default zone.
320      * <p>
321      * This method returns a MutableDateTime object in the default zone.
322      * This differs from the similarly named method on DateTime, DateMidnight
323      * or MutableDateTime which retains the time zone. The difference is
324      * because Instant really represents a time <i>without</i> a zone,
325      * thus calling this method we really have no zone to 'retain' and
326      * hence expect to switch to the default zone.
327      * <p>
328      * This method definition preserves compatibility with earlier versions
329      * of Joda-Time.
330      *
331      * @return a MutableDateTime using the same millis
332      */
333     public MutableDateTime toMutableDateTime() {
334         return new MutableDateTime(getMillis(), ISOChronology.getInstance());
335     }
336 
337     /**
338      * Get this object as a MutableDateTime using ISOChronology in the default zone.
339      * This method is identical to <code>toMutableDateTime()</code>.
340      * <p>
341      * This method returns a MutableDateTime object in the default zone.
342      * This differs from the similarly named method on DateTime, DateMidnight
343      * or MutableDateTime which retains the time zone. The difference is
344      * because Instant really represents a time <i>without</i> a zone,
345      * thus calling this method we really have no zone to 'retain' and
346      * hence expect to switch to the default zone.
347      * <p>
348      * This method is deprecated because it is a duplicate of {@link #toMutableDateTime()}.
349      * However, removing it would cause the superclass implementation to be used,
350      * which would create silent bugs in any caller depending on this implementation.
351      * As such, the method itself is not currently planned to be removed.
352      * <p>
353      * This method definition preserves compatibility with earlier versions
354      * of Joda-Time.
355      *
356      * @return a MutableDateTime using the same millis with ISOChronology
357      * @deprecated Use toMutableDateTime() as it is identical
358      */
359     @Deprecated
360     public MutableDateTime toMutableDateTimeISO() {
361         return toMutableDateTime();
362     }
363 
364 }