001/* 002 * Copyright 2001-2006 Stephen Colebourne 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.joda.time; 017 018import java.io.Serializable; 019 020import org.joda.time.base.AbstractInstant; 021import org.joda.time.chrono.ISOChronology; 022import org.joda.time.convert.ConverterManager; 023import org.joda.time.convert.InstantConverter; 024 025/** 026 * Instant is the standard implementation of a fully immutable instant in time. 027 * <p> 028 * <code>Instant</code> is an implementation of {@link ReadableInstant}. 029 * As with all instants, it represents an exact point on the time-line, 030 * but limited to the precision of milliseconds. An <code>Instant</code> 031 * should be used to represent a point in time irrespective of any other 032 * factor, such as chronology or time zone. 033 * <p> 034 * Internally, the class holds one piece of data, the instant as milliseconds 035 * from the Java epoch of 1970-01-01T00:00:00Z. 036 * <p> 037 * For example, an Instant can be used to compare two <code>DateTime</code> 038 * objects irrespective of chronology or time zone. 039 * <pre> 040 * boolean sameInstant = dt1.toInstant().equals(dt2.toInstant()); 041 * </pre> 042 * Note that the following code will also perform the same check: 043 * <pre> 044 * boolean sameInstant = dt1.isEqual(dt2); 045 * </pre> 046 * <p> 047 * Instant is thread-safe and immutable. 048 * 049 * @author Stephen Colebourne 050 * @since 1.0 051 */ 052public final class Instant 053 extends AbstractInstant 054 implements ReadableInstant, Serializable { 055 056 /** Serialization lock */ 057 private static final long serialVersionUID = 3299096530934209741L; 058 059 /** The millis from 1970-01-01T00:00:00Z */ 060 private final long iMillis; 061 062 //----------------------------------------------------------------------- 063 /** 064 * Constructs an instance set to the current system millisecond time. 065 */ 066 public Instant() { 067 super(); 068 iMillis = DateTimeUtils.currentTimeMillis(); 069 } 070 071 /** 072 * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z. 073 * 074 * @param instant the milliseconds from 1970-01-01T00:00:00Z 075 */ 076 public Instant(long instant) { 077 super(); 078 iMillis = instant; 079 } 080 081 /** 082 * Constructs an instance from an Object that represents a datetime. 083 * <p> 084 * The recognised object types are defined in {@link ConverterManager} and 085 * include String, Calendar and Date. 086 * 087 * @param instant the datetime object, null means now 088 * @throws IllegalArgumentException if the instant is invalid 089 */ 090 public Instant(Object instant) { 091 super(); 092 InstantConverter converter = ConverterManager.getInstance().getInstantConverter(instant); 093 iMillis = converter.getInstantMillis(instant, ISOChronology.getInstanceUTC()); 094 } 095 096 //----------------------------------------------------------------------- 097 /** 098 * Get this object as an Instant by returning <code>this</code>. 099 * 100 * @return <code>this</code> 101 */ 102 public Instant toInstant() { 103 return this; 104 } 105 106 //----------------------------------------------------------------------- 107 /** 108 * Gets a copy of this instant with different millis. 109 * <p> 110 * The returned object will be either be a new Instant or <code>this</code>. 111 * 112 * @param newMillis the new millis, from 1970-01-01T00:00:00Z 113 * @return a copy of this instant with different millis 114 */ 115 public Instant withMillis(long newMillis) { 116 return (newMillis == iMillis ? this : new Instant(newMillis)); 117 } 118 119 /** 120 * Gets a copy of this instant with the specified duration added. 121 * <p> 122 * If the addition is zero, then <code>this</code> is returned. 123 * 124 * @param durationToAdd the duration to add to this one 125 * @param scalar the amount of times to add, such as -1 to subtract once 126 * @return a copy of this instant with the duration added 127 * @throws ArithmeticException if the new instant exceeds the capacity of a long 128 */ 129 public Instant withDurationAdded(long durationToAdd, int scalar) { 130 if (durationToAdd == 0 || scalar == 0) { 131 return this; 132 } 133 long instant = getChronology().add(getMillis(), durationToAdd, scalar); 134 return withMillis(instant); 135 } 136 137 /** 138 * Gets a copy of this instant with the specified duration added. 139 * <p> 140 * If the addition is zero, then <code>this</code> is returned. 141 * 142 * @param durationToAdd the duration to add to this one, null means zero 143 * @param scalar the amount of times to add, such as -1 to subtract once 144 * @return a copy of this instant with the duration added 145 * @throws ArithmeticException if the new instant exceeds the capacity of a long 146 */ 147 public Instant withDurationAdded(ReadableDuration durationToAdd, int scalar) { 148 if (durationToAdd == null || scalar == 0) { 149 return this; 150 } 151 return withDurationAdded(durationToAdd.getMillis(), scalar); 152 } 153 154 //----------------------------------------------------------------------- 155 /** 156 * Gets a copy of this instant with the specified duration added. 157 * <p> 158 * If the amount is zero or null, then <code>this</code> is returned. 159 * 160 * @param duration the duration to add to this one 161 * @return a copy of this instant with the duration added 162 * @throws ArithmeticException if the new instant exceeds the capacity of a long 163 */ 164 public Instant plus(long duration) { 165 return withDurationAdded(duration, 1); 166 } 167 168 /** 169 * Gets a copy of this instant with the specified duration added. 170 * <p> 171 * If the amount is zero or null, then <code>this</code> is returned. 172 * 173 * @param duration the duration to add to this one, null means zero 174 * @return a copy of this instant with the duration added 175 * @throws ArithmeticException if the new instant exceeds the capacity of a long 176 */ 177 public Instant plus(ReadableDuration duration) { 178 return withDurationAdded(duration, 1); 179 } 180 181 //----------------------------------------------------------------------- 182 /** 183 * Gets a copy of this instant with the specified duration taken away. 184 * <p> 185 * If the amount is zero or null, then <code>this</code> is returned. 186 * 187 * @param duration the duration to reduce this instant by 188 * @return a copy of this instant with the duration taken away 189 * @throws ArithmeticException if the new instant exceeds the capacity of a long 190 */ 191 public Instant minus(long duration) { 192 return withDurationAdded(duration, -1); 193 } 194 195 /** 196 * Gets a copy of this instant with the specified duration taken away. 197 * <p> 198 * If the amount is zero or null, then <code>this</code> is returned. 199 * 200 * @param duration the duration to reduce this instant by 201 * @return a copy of this instant with the duration taken away 202 * @throws ArithmeticException if the new instant exceeds the capacity of a long 203 */ 204 public Instant minus(ReadableDuration duration) { 205 return withDurationAdded(duration, -1); 206 } 207 208 //----------------------------------------------------------------------- 209 /** 210 * Gets the milliseconds of the instant. 211 * 212 * @return the number of milliseconds since 1970-01-01T00:00:00Z 213 */ 214 public long getMillis() { 215 return iMillis; 216 } 217 218 /** 219 * Gets the chronology of the instant, which is ISO in the UTC zone. 220 * <p> 221 * This method returns {@link ISOChronology#getInstanceUTC()} which 222 * corresponds to the definition of the Java epoch 1970-01-01T00:00:00Z. 223 * 224 * @return ISO in the UTC zone 225 */ 226 public Chronology getChronology() { 227 return ISOChronology.getInstanceUTC(); 228 } 229 230 //----------------------------------------------------------------------- 231 /** 232 * Get this object as a DateTime using ISOChronology in the default zone. 233 * <p> 234 * This method returns a DateTime object in the default zone. 235 * This differs from the similarly named method on DateTime, DateMidnight 236 * or MutableDateTime which retains the time zone. The difference is 237 * because Instant really represents a time <i>without</i> a zone, 238 * thus calling this method we really have no zone to 'retain' and 239 * hence expect to switch to the default zone. 240 * <p> 241 * This method definition preserves compatability with earlier versions 242 * of Joda-Time. 243 * 244 * @return a DateTime using the same millis 245 */ 246 public DateTime toDateTime() { 247 return new DateTime(getMillis(), ISOChronology.getInstance()); 248 } 249 250 /** 251 * Get this object as a DateTime using ISOChronology in the default zone. 252 * This method is identical to <code>toDateTime()</code>. 253 * <p> 254 * This method returns a DateTime object in the default zone. 255 * This differs from the similarly named method on DateTime, DateMidnight 256 * or MutableDateTime which retains the time zone. The difference is 257 * because Instant really represents a time <i>without</i> a zone, 258 * thus calling this method we really have no zone to 'retain' and 259 * hence expect to switch to the default zone. 260 * <p> 261 * This method definition preserves compatability with earlier versions 262 * of Joda-Time. 263 * 264 * @return a DateTime using the same millis with ISOChronology 265 * @deprecated Use toDateTime() as it is identical 266 */ 267 public DateTime toDateTimeISO() { 268 return toDateTime(); 269 } 270 271 /** 272 * Get this object as a MutableDateTime using ISOChronology in the default zone. 273 * <p> 274 * This method returns a MutableDateTime object in the default zone. 275 * This differs from the similarly named method on DateTime, DateMidnight 276 * or MutableDateTime which retains the time zone. The difference is 277 * because Instant really represents a time <i>without</i> a zone, 278 * thus calling this method we really have no zone to 'retain' and 279 * hence expect to switch to the default zone. 280 * <p> 281 * This method definition preserves compatability with earlier versions 282 * of Joda-Time. 283 * 284 * @return a MutableDateTime using the same millis 285 */ 286 public MutableDateTime toMutableDateTime() { 287 return new MutableDateTime(getMillis(), ISOChronology.getInstance()); 288 } 289 290 /** 291 * Get this object as a MutableDateTime using ISOChronology in the default zone. 292 * This method is identical to <code>toMutableDateTime()</code>. 293 * <p> 294 * This method returns a MutableDateTime object in the default zone. 295 * This differs from the similarly named method on DateTime, DateMidnight 296 * or MutableDateTime which retains the time zone. The difference is 297 * because Instant really represents a time <i>without</i> a zone, 298 * thus calling this method we really have no zone to 'retain' and 299 * hence expect to switch to the default zone. 300 * <p> 301 * This method definition preserves compatability with earlier versions 302 * of Joda-Time. 303 * 304 * @return a MutableDateTime using the same millis with ISOChronology 305 * @deprecated Use toMutableDateTime() as it is identical 306 */ 307 public MutableDateTime toMutableDateTimeISO() { 308 return toMutableDateTime(); 309 } 310 311}