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 }