KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > time > Month


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
24  * in the United States and other countries.]
25  *
26  * ----------
27  * Month.java
28  * ----------
29  * (C) Copyright 2001-2005, by Object Refinery Limited.
30  *
31  * Original Author: David Gilbert (for Object Refinery Limited);
32  * Contributor(s): -;
33  *
34  * $Id: Month.java,v 1.7 2005/05/19 10:35:27 mungady Exp $
35  *
36  * Changes
37  * -------
38  * 11-Oct-2001 : Version 1 (DG);
39  * 14-Nov-2001 : Added method to get year as primitive (DG);
40  * Override for toString() method (DG);
41  * 18-Dec-2001 : Changed order of parameters in constructor (DG);
42  * 19-Dec-2001 : Added a new constructor as suggested by Paul English (DG);
43  * 29-Jan-2002 : Worked on the parseMonth() method (DG);
44  * 14-Feb-2002 : Fixed bugs in the Month constructors (DG);
45  * 26-Feb-2002 : Changed getStart(), getMiddle() and getEnd() methods to
46  * evaluate with reference to a particular time zone (DG);
47  * 19-Mar-2002 : Changed API for TimePeriod classes (DG);
48  * 10-Sep-2002 : Added getSerialIndex() method (DG);
49  * 04-Oct-2002 : Fixed errors reported by Checkstyle (DG);
50  * 10-Jan-2003 : Changed base class and method names (DG);
51  * 13-Mar-2003 : Moved to com.jrefinery.data.time package, and implemented
52  * Serializable (DG);
53  * 21-Oct-2003 : Added hashCode() method (DG);
54  *
55  */

56
57 package org.jfree.data.time;
58
59 import java.io.Serializable JavaDoc;
60 import java.util.Calendar JavaDoc;
61 import java.util.Date JavaDoc;
62 import java.util.TimeZone JavaDoc;
63
64 import org.jfree.date.MonthConstants;
65 import org.jfree.date.SerialDate;
66
67 /**
68  * Represents a single month. This class is immutable, which is a requirement
69  * for all {@link RegularTimePeriod} subclasses.
70  */

71 public class Month extends RegularTimePeriod implements Serializable JavaDoc {
72
73     /** For serialization. */
74     private static final long serialVersionUID = -5090216912548722570L;
75
76     /** The month (1-12). */
77     private int month;
78
79     /** The year in which the month falls. */
80     private Year year;
81
82     /**
83      * Constructs a new Month, based on the current system time.
84      */

85     public Month() {
86         this(new Date JavaDoc());
87     }
88
89     /**
90      * Constructs a new month instance.
91      *
92      * @param month the month (in the range 1 to 12).
93      * @param year the year.
94      */

95     public Month(int month, int year) {
96         this(month, new Year(year));
97     }
98
99     /**
100      * Constructs a new month instance.
101      *
102      * @param month the month (in the range 1 to 12).
103      * @param year the year.
104      */

105     public Month(int month, Year year) {
106
107         if ((month < 1) && (month > 12)) {
108             throw new IllegalArgumentException JavaDoc("Month outside valid range.");
109         }
110         this.month = month;
111         this.year = year;
112
113     }
114
115     /**
116      * Constructs a new month instance, based on a date/time and the default
117      * time zone.
118      *
119      * @param time the date/time.
120      */

121     public Month(Date JavaDoc time) {
122         this(time, RegularTimePeriod.DEFAULT_TIME_ZONE);
123     }
124
125     /**
126      * Constructs a Month, based on a date/time and a time zone.
127      *
128      * @param time the date/time.
129      * @param zone the time zone.
130      */

131     public Month(Date JavaDoc time, TimeZone JavaDoc zone) {
132         Calendar JavaDoc calendar = Calendar.getInstance(zone);
133         calendar.setTime(time);
134         this.month = calendar.get(Calendar.MONTH) + 1;
135         this.year = new Year(calendar.get(Calendar.YEAR));
136     }
137
138     /**
139      * Returns the year in which the month falls.
140      *
141      * @return The year in which the month falls (as a Year object).
142      */

143     public Year getYear() {
144         return this.year;
145     }
146
147     /**
148      * Returns the year in which the month falls.
149      *
150      * @return The year in which the monht falls (as an int).
151      */

152     public int getYearValue() {
153         return this.year.getYear();
154     }
155
156     /**
157      * Returns the month. Note that 1=JAN, 2=FEB, ...
158      *
159      * @return The month.
160      */

161     public int getMonth() {
162         return this.month;
163     }
164
165     /**
166      * Returns the month preceding this one.
167      *
168      * @return The month preceding this one.
169      */

170     public RegularTimePeriod previous() {
171
172         Month result;
173         if (this.month != MonthConstants.JANUARY) {
174             result = new Month(this.month - 1, this.year);
175         }
176         else {
177             Year prevYear = (Year) this.year.previous();
178             if (prevYear != null) {
179                 result = new Month(MonthConstants.DECEMBER, prevYear);
180             }
181             else {
182                 result = null;
183             }
184         }
185         return result;
186
187     }
188
189     /**
190      * Returns the month following this one.
191      *
192      * @return The month following this one.
193      */

194     public RegularTimePeriod next() {
195         Month result;
196         if (this.month != MonthConstants.DECEMBER) {
197             result = new Month(this.month + 1, this.year);
198         }
199         else {
200             Year nextYear = (Year) this.year.next();
201             if (nextYear != null) {
202                 result = new Month(MonthConstants.JANUARY, nextYear);
203             }
204             else {
205                 result = null;
206             }
207         }
208         return result;
209     }
210
211     /**
212      * Returns a serial index number for the month.
213      *
214      * @return The serial index number.
215      */

216     public long getSerialIndex() {
217         return this.year.getYear() * 12L + this.month;
218     }
219
220     /**
221      * Returns a string representing the month (e.g. "January 2002").
222      * <P>
223      * To do: look at internationalisation.
224      *
225      * @return A string representing the month.
226      */

227     public String JavaDoc toString() {
228         return SerialDate.monthCodeToString(this.month) + " " + this.year;
229     }
230
231     /**
232      * Tests the equality of this Month object to an arbitrary object.
233      * Returns true if the target is a Month instance representing the same
234      * month as this object. In all other cases, returns false.
235      *
236      * @param obj the object.
237      *
238      * @return <code>true</code> if month and year of this and object are the
239      * same.
240      */

241     public boolean equals(Object JavaDoc obj) {
242
243         if (obj != null) {
244             if (obj instanceof Month) {
245                 Month target = (Month) obj;
246                 return (
247                     (this.month == target.getMonth())
248                         && (this.year.equals(target.getYear()))
249                 );
250             }
251             else {
252                 return false;
253             }
254         }
255         else {
256             return false;
257         }
258
259     }
260
261     /**
262      * Returns a hash code for this object instance. The approach described by
263      * Joshua Bloch in "Effective Java" has been used here:
264      * <p>
265      * <code>http://developer.java.sun.com/developer/Books/effectivejava
266      * /Chapter3.pdf</code>
267      *
268      * @return A hash code.
269      */

270     public int hashCode() {
271         int result = 17;
272         result = 37 * result + this.month;
273         result = 37 * result + this.year.hashCode();
274         return result;
275     }
276
277     /**
278      * Returns an integer indicating the order of this Month object relative to
279      * the specified
280      * object: negative == before, zero == same, positive == after.
281      *
282      * @param o1 the object to compare.
283      *
284      * @return negative == before, zero == same, positive == after.
285      */

286     public int compareTo(Object JavaDoc o1) {
287
288         int result;
289
290         // CASE 1 : Comparing to another Month object
291
// --------------------------------------------
292
if (o1 instanceof Month) {
293             Month m = (Month) o1;
294             result = this.year.getYear() - m.getYear().getYear();
295             if (result == 0) {
296                 result = this.month - m.getMonth();
297             }
298         }
299
300         // CASE 2 : Comparing to another TimePeriod object
301
// -----------------------------------------------
302
else if (o1 instanceof RegularTimePeriod) {
303             // more difficult case - evaluate later...
304
result = 0;
305         }
306
307         // CASE 3 : Comparing to a non-TimePeriod object
308
// ---------------------------------------------
309
else {
310             // consider time periods to be ordered after general objects
311
result = 1;
312         }
313
314         return result;
315
316     }
317
318     /**
319      * Returns the first millisecond of the month, evaluated using the supplied
320      * calendar (which determines the time zone).
321      *
322      * @param calendar the calendar.
323      *
324      * @return The first millisecond of the month.
325      */

326     public long getFirstMillisecond(Calendar JavaDoc calendar) {
327         Day first = new Day(1, this.month, this.year.getYear());
328         return first.getFirstMillisecond(calendar);
329     }
330
331     /**
332      * Returns the last millisecond of the month, evaluated using the supplied
333      * calendar (which determines the time zone).
334      *
335      * @param calendar the calendar.
336      *
337      * @return The last millisecond of the month.
338      */

339     public long getLastMillisecond(Calendar JavaDoc calendar) {
340         int eom = SerialDate.lastDayOfMonth(this.month, this.year.getYear());
341         Day last = new Day(eom, this.month, this.year.getYear());
342         return last.getLastMillisecond(calendar);
343     }
344
345     /**
346      * Parses the string argument as a month.
347      * <P>
348      * This method is required to accept the format "YYYY-MM". It will also
349      * accept "MM-YYYY". Anything else, at the moment, is a bonus.
350      *
351      * @param s the string to parse.
352      *
353      * @return <code>null</code> if the string is not parseable, the month
354      * otherwise.
355      */

356     public static Month parseMonth(String JavaDoc s) {
357
358         Month result = null;
359         if (s != null) {
360
361             // trim whitespace from either end of the string
362
s = s.trim();
363
364             int i = Month.findSeparator(s);
365             if (i != -1) {
366                 String JavaDoc s1 = s.substring(0, i).trim();
367                 String JavaDoc s2 = s.substring(i + 1, s.length()).trim();
368
369                 Year year = Month.evaluateAsYear(s1);
370                 int month;
371                 if (year != null) {
372                     month = SerialDate.stringToMonthCode(s2);
373                     if (month == -1) {
374                         throw new TimePeriodFormatException(
375                             "Can't evaluate the month."
376                         );
377                     }
378                     result = new Month(month, year);
379                 }
380                 else {
381                     year = Month.evaluateAsYear(s2);
382                     if (year != null) {
383                         month = SerialDate.stringToMonthCode(s1);
384                         if (month == -1) {
385                             throw new TimePeriodFormatException(
386                                 "Can't evaluate the month."
387                             );
388                         }
389                         result = new Month(month, year);
390                     }
391                     else {
392                         throw new TimePeriodFormatException(
393                             "Can't evaluate the year."
394                         );
395                     }
396                 }
397
398             }
399             else {
400                 throw new TimePeriodFormatException(
401                     "Could not find separator."
402                 );
403             }
404
405         }
406         return result;
407
408     }
409
410     /**
411      * Finds the first occurrence of ' ', '-', ',' or '.'
412      *
413      * @param s the string to parse.
414      *
415      * @return <code>-1</code> if none of the characters where found, the
416      * position of the first occurence otherwise.
417      */

418     private static int findSeparator(String JavaDoc s) {
419
420         int result = s.indexOf('-');
421         if (result == -1) {
422             result = s.indexOf(',');
423         }
424         if (result == -1) {
425             result = s.indexOf(' ');
426         }
427         if (result == -1) {
428             result = s.indexOf('.');
429         }
430         return result;
431     }
432
433     /**
434      * Creates a year from a string, or returns null (format exceptions
435      * suppressed).
436      *
437      * @param s the string to parse.
438      *
439      * @return <code>null</code> if the string is not parseable, the year
440      * otherwise.
441      */

442     private static Year evaluateAsYear(String JavaDoc s) {
443
444         Year result = null;
445         try {
446             result = Year.parseYear(s);
447         }
448         catch (TimePeriodFormatException e) {
449             // suppress
450
}
451         return result;
452
453     }
454
455 }
456
Popular Tags