001 /* 002 * Copyright 2001-2011 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 */ 016 package org.joda.time.base; 017 018 import java.io.Serializable; 019 020 import org.joda.time.Chronology; 021 import org.joda.time.DateTimeUtils; 022 import org.joda.time.Interval; 023 import org.joda.time.Period; 024 import org.joda.time.PeriodType; 025 import org.joda.time.ReadableDuration; 026 import org.joda.time.ReadableInstant; 027 import org.joda.time.convert.ConverterManager; 028 import org.joda.time.convert.DurationConverter; 029 import org.joda.time.field.FieldUtils; 030 031 /** 032 * BaseDuration is an abstract implementation of ReadableDuration that stores 033 * data in a <code>long</code> duration milliseconds field. 034 * <p> 035 * This class should generally not be used directly by API users. 036 * The {@link ReadableDuration} interface should be used when different 037 * kinds of duration objects are to be referenced. 038 * <p> 039 * BaseDuration subclasses may be mutable and not thread-safe. 040 * 041 * @author Brian S O'Neill 042 * @author Stephen Colebourne 043 * @since 1.0 044 */ 045 public abstract class BaseDuration 046 extends AbstractDuration 047 implements ReadableDuration, Serializable { 048 049 /** Serialization version */ 050 private static final long serialVersionUID = 2581698638990L; 051 052 /** The duration length */ 053 private volatile long iMillis; 054 055 /** 056 * Creates a duration from the given millisecond duration. 057 * 058 * @param duration the duration, in milliseconds 059 */ 060 protected BaseDuration(long duration) { 061 super(); 062 iMillis = duration; 063 } 064 065 /** 066 * Creates a duration from the given interval endpoints. 067 * 068 * @param startInstant interval start, in milliseconds 069 * @param endInstant interval end, in milliseconds 070 * @throws ArithmeticException if the duration exceeds a 64 bit long 071 */ 072 protected BaseDuration(long startInstant, long endInstant) { 073 super(); 074 iMillis = FieldUtils.safeAdd(endInstant, -startInstant); 075 } 076 077 /** 078 * Creates a duration from the given interval endpoints. 079 * 080 * @param start interval start, null means now 081 * @param end interval end, null means now 082 * @throws ArithmeticException if the duration exceeds a 64 bit long 083 */ 084 protected BaseDuration(ReadableInstant start, ReadableInstant end) { 085 super(); 086 if (start == end) { 087 iMillis = 0L; 088 } else { 089 long startMillis = DateTimeUtils.getInstantMillis(start); 090 long endMillis = DateTimeUtils.getInstantMillis(end); 091 iMillis = FieldUtils.safeAdd(endMillis, -startMillis); 092 } 093 } 094 095 /** 096 * Creates a duration from the specified object using the 097 * {@link org.joda.time.convert.ConverterManager ConverterManager}. 098 * 099 * @param duration duration to convert 100 * @throws IllegalArgumentException if duration is invalid 101 */ 102 protected BaseDuration(Object duration) { 103 super(); 104 DurationConverter converter = ConverterManager.getInstance().getDurationConverter(duration); 105 iMillis = converter.getDurationMillis(duration); 106 } 107 108 //----------------------------------------------------------------------- 109 /** 110 * Gets the length of this duration in milliseconds. 111 * 112 * @return the length of the duration in milliseconds. 113 */ 114 public long getMillis() { 115 return iMillis; 116 } 117 118 //----------------------------------------------------------------------- 119 /** 120 * Sets the length of this duration in milliseconds. 121 * 122 * @param duration the new length of the duration 123 */ 124 protected void setMillis(long duration) { 125 iMillis = duration; 126 } 127 128 //----------------------------------------------------------------------- 129 /** 130 * Converts this duration to a Period instance using the specified period type 131 * and the ISO chronology. 132 * <p> 133 * Only precise fields in the period type will be used. 134 * At most these are hours, minutes, seconds and millis - the period 135 * type may restrict the selection further. 136 * <p> 137 * For more control over the conversion process, you must pair the duration with 138 * an instant, see {@link #toPeriodFrom(ReadableInstant, PeriodType)}. 139 * 140 * @param type the period type to use, null means standard 141 * @return a Period created using the millisecond duration from this instance 142 */ 143 public Period toPeriod(PeriodType type) { 144 return new Period(getMillis(), type); 145 } 146 147 /** 148 * Converts this duration to a Period instance using the standard period type 149 * and the specified chronology. 150 * <p> 151 * Only precise fields in the period type will be used. 152 * Exactly which fields are precise depends on the chronology. 153 * Only the time fields are precise for ISO chronology with a time zone. 154 * However, ISO UTC also has precise days and weeks. 155 * <p> 156 * For more control over the conversion process, you must pair the duration with 157 * an instant, see {@link #toPeriodFrom(ReadableInstant)} and 158 * {@link #toPeriodTo(ReadableInstant)} 159 * 160 * @param chrono the chronology to use, null means ISO default 161 * @return a Period created using the millisecond duration from this instance 162 */ 163 public Period toPeriod(Chronology chrono) { 164 return new Period(getMillis(), chrono); 165 } 166 167 /** 168 * Converts this duration to a Period instance using the specified period type 169 * and chronology. 170 * <p> 171 * Only precise fields in the period type will be used. 172 * Exactly which fields are precise depends on the chronology. 173 * Only the time fields are precise for ISO chronology with a time zone. 174 * However, ISO UTC also has precise days and weeks. 175 * <p> 176 * For more control over the conversion process, you must pair the duration with 177 * an instant, see {@link #toPeriodFrom(ReadableInstant, PeriodType)} and 178 * {@link #toPeriodTo(ReadableInstant, PeriodType)} 179 * 180 * @param type the period type to use, null means standard 181 * @param chrono the chronology to use, null means ISO default 182 * @return a Period created using the millisecond duration from this instance 183 */ 184 public Period toPeriod(PeriodType type, Chronology chrono) { 185 return new Period(getMillis(), type, chrono); 186 } 187 188 /** 189 * Converts this duration to a Period instance by adding the duration to a start 190 * instant to obtain an interval using the standard period type. 191 * <p> 192 * This conversion will determine the fields of a period accurately. 193 * The results are based on the instant millis, the chronology of the instant, 194 * the standard period type and the length of this duration. 195 * 196 * @param startInstant the instant to calculate the period from, null means now 197 * @return a Period created using the millisecond duration from this instance 198 */ 199 public Period toPeriodFrom(ReadableInstant startInstant) { 200 return new Period(startInstant, this); 201 } 202 203 /** 204 * Converts this duration to a Period instance by adding the duration to a start 205 * instant to obtain an interval. 206 * <p> 207 * This conversion will determine the fields of a period accurately. 208 * The results are based on the instant millis, the chronology of the instant, 209 * the period type and the length of this duration. 210 * 211 * @param startInstant the instant to calculate the period from, null means now 212 * @param type the period type determining how to split the duration into fields, null means All type 213 * @return a Period created using the millisecond duration from this instance 214 */ 215 public Period toPeriodFrom(ReadableInstant startInstant, PeriodType type) { 216 return new Period(startInstant, this, type); 217 } 218 219 /** 220 * Converts this duration to a Period instance by subtracting the duration 221 * from an end instant to obtain an interval using the standard period 222 * type. 223 * <p> 224 * This conversion will determine the fields of a period accurately. 225 * The results are based on the instant millis, the chronology of the instant, 226 * the standard period type and the length of this duration. 227 * 228 * @param endInstant the instant to calculate the period to, null means now 229 * @return a Period created using the millisecond duration from this instance 230 */ 231 public Period toPeriodTo(ReadableInstant endInstant) { 232 return new Period(this, endInstant); 233 } 234 235 /** 236 * Converts this duration to a Period instance by subtracting the duration 237 * from an end instant to obtain an interval using the standard period 238 * type. 239 * <p> 240 * This conversion will determine the fields of a period accurately. 241 * The results are based on the instant millis, the chronology of the instant, 242 * the period type and the length of this duration. 243 * 244 * @param endInstant the instant to calculate the period to, null means now 245 * @param type the period type determining how to split the duration into fields, null means All type 246 * @return a Period created using the millisecond duration from this instance 247 */ 248 public Period toPeriodTo(ReadableInstant endInstant, PeriodType type) { 249 return new Period(this, endInstant, type); 250 } 251 252 /** 253 * Converts this duration to an Interval starting at the specified instant. 254 * 255 * @param startInstant the instant to start the interval at, null means now 256 * @return an Interval starting at the specified instant 257 */ 258 public Interval toIntervalFrom(ReadableInstant startInstant) { 259 return new Interval(startInstant, this); 260 } 261 262 /** 263 * Converts this duration to an Interval ending at the specified instant. 264 * 265 * @param endInstant the instant to end the interval at, null means now 266 * @return an Interval ending at the specified instant 267 */ 268 public Interval toIntervalTo(ReadableInstant endInstant) { 269 return new Interval(this, endInstant); 270 } 271 272 }