KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > Months


1 /*
2  * Copyright 2001-2006 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 org.joda.time.base.BaseSingleFieldPeriod;
19 import org.joda.time.field.FieldUtils;
20 import org.joda.time.format.ISOPeriodFormat;
21 import org.joda.time.format.PeriodFormatter;
22
23 /**
24  * An immutable time period representing a number of months.
25  * <p>
26  * <code>Months</code> is an immutable period that can only store months.
27  * It does not store years, days or hours for example. As such it is a
28  * type-safe way of representing a number of months in an application.
29  * <p>
30  * The number of months is set in the constructor, and may be queried using
31  * <code>getMonths()</code>. Basic mathematical operations are provided -
32  * <code>plus()</code>, <code>minus()</code>, <code>multipliedBy()</code> and
33  * <code>dividedBy()</code>.
34  * <p>
35  * <code>Months</code> is thread-safe and immutable.
36  *
37  * @author Stephen Colebourne
38  * @since 1.4
39  */

40 public final class Months extends BaseSingleFieldPeriod {
41
42     /** Constant representing zero months. */
43     public static final Months ZERO = new Months(0);
44     /** Constant representing one day. */
45     public static final Months ONE = new Months(1);
46     /** Constant representing two months. */
47     public static final Months TWO = new Months(2);
48     /** Constant representing three months. */
49     public static final Months THREE = new Months(3);
50     /** Constant representing four months. */
51     public static final Months FOUR = new Months(4);
52     /** Constant representing five months. */
53     public static final Months FIVE = new Months(5);
54     /** Constant representing six months. */
55     public static final Months SIX = new Months(6);
56     /** Constant representing seven months. */
57     public static final Months SEVEN = new Months(7);
58     /** Constant representing eight months. */
59     public static final Months EIGHT = new Months(8);
60     /** Constant representing nine months. */
61     public static final Months NINE = new Months(9);
62     /** Constant representing ten months. */
63     public static final Months TEN = new Months(10);
64     /** Constant representing eleven months. */
65     public static final Months ELEVEN = new Months(11);
66     /** Constant representing twelve months. */
67     public static final Months TWELVE = new Months(12);
68     /** Constant representing the maximum nuber of months that can be stored in this object. */
69     public static final Months MAX_VALUE = new Months(Integer.MAX_VALUE);
70     /** Constant representing the minimum nuber of months that can be stored in this object. */
71     public static final Months MIN_VALUE = new Months(Integer.MIN_VALUE);
72
73     /** The paser to use for this class. */
74     private static final PeriodFormatter PARSER = ISOPeriodFormat.standard().withParseType(PeriodType.months());
75     /** Serialization version. */
76     private static final long serialVersionUID = 87525275727380867L;
77
78     //-----------------------------------------------------------------------
79
/**
80      * Obtains an instance of <code>Months</code> that may be cached.
81      * <code>Months</code> is immutable, so instances can be cached and shared.
82      * This factory method provides access to shared instances.
83      *
84      * @param months the number of months to obtain an instance for
85      * @return the instance of Months
86      */

87     public static Months months(int months) {
88         switch (months) {
89             case 0:
90                 return ZERO;
91             case 1:
92                 return ONE;
93             case 2:
94                 return TWO;
95             case 3:
96                 return THREE;
97             case 4:
98                 return FOUR;
99             case 5:
100                 return FIVE;
101             case 6:
102                 return SIX;
103             case 7:
104                 return SEVEN;
105             case 8:
106                 return EIGHT;
107             case 9:
108                 return NINE;
109             case 10:
110                 return TEN;
111             case 11:
112                 return ELEVEN;
113             case 12:
114                 return TWELVE;
115             case Integer.MAX_VALUE:
116                 return MAX_VALUE;
117             case Integer.MIN_VALUE:
118                 return MIN_VALUE;
119             default:
120                 return new Months(months);
121         }
122     }
123
124     //-----------------------------------------------------------------------
125
/**
126      * Creates a <code>Months</code> representing the number of whole months
127      * between the two specified datetimes. This method corectly handles
128      * any daylight savings time changes that may occur during the interval.
129      *
130      * @param start the start instant, must not be null
131      * @param end the end instant, must not be null
132      * @return the period in months
133      * @throws IllegalArgumentException if the instants are null or invalid
134      */

135     public static Months monthsBetween(ReadableInstant start, ReadableInstant end) {
136         int amount = BaseSingleFieldPeriod.between(start, end, DurationFieldType.months());
137         return Months.months(amount);
138     }
139
140     /**
141      * Creates a <code>Months</code> representing the number of whole months
142      * between the two specified partial datetimes.
143      * <p>
144      * The two partials must contain the same fields, for example you can specify
145      * two <code>LocalDate</code> objects.
146      *
147      * @param start the start partial date, must not be null
148      * @param end the end partial date, must not be null
149      * @return the period in months
150      * @throws IllegalArgumentException if the partials are null or invalid
151      */

152     public static Months monthsBetween(ReadablePartial start, ReadablePartial end) {
153         if (start instanceof LocalDate && end instanceof LocalDate) {
154             Chronology chrono = DateTimeUtils.getChronology(start.getChronology());
155             int months = chrono.months().getDifference(
156                     ((LocalDate) end).getLocalMillis(), ((LocalDate) start).getLocalMillis());
157             return Months.months(months);
158         }
159         int amount = BaseSingleFieldPeriod.between(start, end, ZERO);
160         return Months.months(amount);
161     }
162
163     /**
164      * Creates a <code>Months</code> representing the number of whole months
165      * in the specified interval. This method corectly handles any daylight
166      * savings time changes that may occur during the interval.
167      *
168      * @param interval the interval to extract months from, null returns zero
169      * @return the period in months
170      * @throws IllegalArgumentException if the partials are null or invalid
171      */

172     public static Months monthsIn(ReadableInterval interval) {
173         if (interval == null) {
174             return Months.ZERO;
175         }
176         int amount = BaseSingleFieldPeriod.between(interval.getStart(), interval.getEnd(), DurationFieldType.months());
177         return Months.months(amount);
178     }
179
180     /**
181      * Creates a new <code>Months</code> by parsing a string in the ISO8601 format 'PnM'.
182      * <p>
183      * The parse will accept the full ISO syntax of PnYnMnWnDTnHnMnS however only the
184      * months component may be non-zero. If any other component is non-zero, an exception
185      * will be thrown.
186      *
187      * @param periodStr the period string, null returns zero
188      * @return the period in months
189      * @throws IllegalArgumentException if the string format is invalid
190      */

191     public static Months parseMonths(String JavaDoc periodStr) {
192         if (periodStr == null) {
193             return Months.ZERO;
194         }
195         Period p = PARSER.parsePeriod(periodStr);
196         return Months.months(p.getMonths());
197     }
198
199     //-----------------------------------------------------------------------
200
/**
201      * Creates a new instance representing a number of months.
202      * You should consider using the factory method {@link #months(int)}
203      * instead of the constructor.
204      *
205      * @param months the number of months to represent
206      */

207     private Months(int months) {
208         super(months);
209     }
210
211     /**
212      * Resolves singletons.
213      *
214      * @return the singleton instance
215      */

216     private Object JavaDoc readResolve() {
217         return Months.months(getValue());
218     }
219
220     //-----------------------------------------------------------------------
221
/**
222      * Gets the duration field type, which is <code>months</code>.
223      *
224      * @return the period type
225      */

226     public DurationFieldType getFieldType() {
227         return DurationFieldType.months();
228     }
229
230     /**
231      * Gets the period type, which is <code>months</code>.
232      *
233      * @return the period type
234      */

235     public PeriodType getPeriodType() {
236         return PeriodType.months();
237     }
238
239     //-----------------------------------------------------------------------
240
/**
241      * Gets the number of months that this period represents.
242      *
243      * @return the number of months in the period
244      */

245     public int getMonths() {
246         return getValue();
247     }
248
249     //-----------------------------------------------------------------------
250
/**
251      * Returns a new instance with the specified number of months added.
252      * <p>
253      * This instance is immutable and unaffected by this method call.
254      *
255      * @param months the amount of months to add, may be negative
256      * @return the new period plus the specified number of months
257      * @throws ArithmeticException if the result overflows an int
258      */

259     public Months plus(int months) {
260         if (months == 0) {
261             return this;
262         }
263         return Months.months(FieldUtils.safeAdd(getValue(), months));
264     }
265
266     /**
267      * Returns a new instance with the specified number of months added.
268      * <p>
269      * This instance is immutable and unaffected by this method call.
270      *
271      * @param months the amount of months to add, may be negative, null means zero
272      * @return the new period plus the specified number of months
273      * @throws ArithmeticException if the result overflows an int
274      */

275     public Months plus(Months months) {
276         if (months == null) {
277             return this;
278         }
279         return plus(months.getValue());
280     }
281
282     //-----------------------------------------------------------------------
283
/**
284      * Returns a new instance with the specified number of months taken away.
285      * <p>
286      * This instance is immutable and unaffected by this method call.
287      *
288      * @param months the amount of months to take away, may be negative
289      * @return the new period minus the specified number of months
290      * @throws ArithmeticException if the result overflows an int
291      */

292     public Months minus(int months) {
293         return plus(FieldUtils.safeNegate(months));
294     }
295
296     /**
297      * Returns a new instance with the specified number of months taken away.
298      * <p>
299      * This instance is immutable and unaffected by this method call.
300      *
301      * @param months the amount of months to take away, may be negative, null means zero
302      * @return the new period minus the specified number of months
303      * @throws ArithmeticException if the result overflows an int
304      */

305     public Months minus(Months months) {
306         if (months == null) {
307             return this;
308         }
309         return minus(months.getValue());
310     }
311
312     //-----------------------------------------------------------------------
313
/**
314      * Returns a new instance with the months multiplied by the specified scalar.
315      * <p>
316      * This instance is immutable and unaffected by this method call.
317      *
318      * @param scalar the amount to multiply by, may be negative
319      * @return the new period multiplied by the specified scalar
320      * @throws ArithmeticException if the result overflows an int
321      */

322     public Months multipliedBy(int scalar) {
323         return Months.months(FieldUtils.safeMultiply(getValue(), scalar));
324     }
325
326     /**
327      * Returns a new instance with the months divided by the specified divisor.
328      * The calculation uses integer division, thus 3 divided by 2 is 1.
329      * <p>
330      * This instance is immutable and unaffected by this method call.
331      *
332      * @param divisor the amount to divide by, may be negative
333      * @return the new period divided by the specified divisor
334      * @throws ArithmeticException if the divisor is zero
335      */

336     public Months dividedBy(int divisor) {
337         if (divisor == 1) {
338             return this;
339         }
340         return Months.months(getValue() / divisor);
341     }
342
343     //-----------------------------------------------------------------------
344
/**
345      * Returns a new instance with the months value negated.
346      *
347      * @return the new period with a negated value
348      * @throws ArithmeticException if the result overflows an int
349      */

350     public Months negated() {
351         return Months.months(FieldUtils.safeNegate(getValue()));
352     }
353
354     //-----------------------------------------------------------------------
355
/**
356      * Is this months instance greater than the specified number of months.
357      *
358      * @param other the other period, null means zero
359      * @return true if this months instance is greater than the specified one
360      */

361     public boolean isGreaterThan(Months other) {
362         if (other == null) {
363             return getValue() > 0;
364         }
365         return getValue() > other.getValue();
366     }
367
368     /**
369      * Is this months instance less than the specified number of months.
370      *
371      * @param other the other period, null means zero
372      * @return true if this months instance is less than the specified one
373      */

374     public boolean isLessThan(Months other) {
375         if (other == null) {
376             return getValue() < 0;
377         }
378         return getValue() < other.getValue();
379     }
380
381     //-----------------------------------------------------------------------
382
/**
383      * Gets this instance as a String in the ISO8601 duration format.
384      * <p>
385      * For example, "P4M" represents 4 months.
386      *
387      * @return the value as an ISO8601 string
388      */

389     public String JavaDoc toString() {
390         return "P" + String.valueOf(getValue()) + "M";
391     }
392
393 }
394
Popular Tags