001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     *
027     * ----------------------
028     * QuarterDateFormat.java
029     * ----------------------
030     * (C) Copyright 2005, by Object Refinery Limited and Contributors.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * $Id: QuarterDateFormat.java,v 1.3.2.2 2005/10/25 20:37:34 mungady Exp $
036     *
037     * Changes:
038     * --------
039     * 01-Mar-2005 : Version 1 (DG);
040     * 10-May-2005 : Added equals() method, and implemented Cloneable and 
041     *               Serializable (DG);
042     *
043     */
044    
045    package org.jfree.chart.axis;
046    
047    import java.io.Serializable;
048    import java.text.DateFormat;
049    import java.text.FieldPosition;
050    import java.text.NumberFormat;
051    import java.text.ParsePosition;
052    import java.util.Arrays;
053    import java.util.Calendar;
054    import java.util.Date;
055    import java.util.GregorianCalendar;
056    import java.util.TimeZone;
057    
058    /**
059     * A formatter that formats dates to show the year and quarter (for example,
060     * '2004 IV' for the last quarter of 2004.
061     */
062    public class QuarterDateFormat extends DateFormat 
063                                   implements Cloneable, Serializable {
064        
065        /** For serialization. */
066        private static final long serialVersionUID = -6738465248529797176L;
067        
068        /** Symbols for regular quarters. */
069        public static final String[] REGULAR_QUARTERS 
070            = new String[] {"1", "2", "3", "4"};
071        
072        /** Symbols for roman numbered quarters. */
073        public static final String[] ROMAN_QUARTERS 
074            = new String[] {"I", "II", "III", "IV"};
075        
076        /** The strings. */
077        private String[] quarters = REGULAR_QUARTERS;
078        
079        /**
080         * Creates a new instance for the default time zone.
081         */
082        public QuarterDateFormat() {
083            this(TimeZone.getDefault());  
084        }
085        
086        /**
087         * Creates a new instance for the specified time zone.
088         * 
089         * @param zone  the time zone (<code>null</code> not permitted).
090         */
091        public QuarterDateFormat(TimeZone zone) {
092            this(zone, REGULAR_QUARTERS);
093        }
094        
095        /**
096         * Creates a new instance for the specified time zone.
097         * 
098         * @param zone  the time zone (<code>null</code> not permitted).
099         * @param quarterSymbols  the quarter symbols.
100         */
101        public QuarterDateFormat(TimeZone zone, String[] quarterSymbols) {
102            if (zone == null) {
103                throw new IllegalArgumentException("Null 'zone' argument.");   
104            }
105            this.calendar = new GregorianCalendar(zone);
106            this.quarters = quarterSymbols;
107            
108            // the following is never used, but it seems that DateFormat requires
109            // it to be non-null.  It isn't well covered in the spec, refer to 
110            // bug parade 5061189 for more info.
111            this.numberFormat = NumberFormat.getNumberInstance();
112        }
113        
114        /**
115         * Formats the given date.
116         * 
117         * @param date  the date.
118         * @param toAppendTo  the string buffer.
119         * @param fieldPosition  the field position.
120         * 
121         * @return The formatted date.
122         */
123        public StringBuffer format(Date date, StringBuffer toAppendTo,
124                                   FieldPosition fieldPosition) {
125            this.calendar.setTime(date);
126            int year = this.calendar.get(Calendar.YEAR);
127            int month = this.calendar.get(Calendar.MONTH);
128            toAppendTo.append(year);
129            toAppendTo.append(" ");
130            int quarter = month / 3;
131            toAppendTo.append(this.quarters[quarter]);
132            return toAppendTo;   
133        }
134    
135        /**
136         * Parses the given string (not implemented).
137         * 
138         * @param source  the date string.
139         * @param pos  the parse position.
140         * 
141         * @return <code>null</code>, as this method has not been implemented.
142         */
143        public Date parse(String source, ParsePosition pos) {
144            return null;   
145        }
146    
147        /**
148         * Tests this formatter for equality with an arbitrary object.
149         * 
150         * @param obj  the object.
151         * 
152         * @return A boolean.
153         */
154        public boolean equals(Object obj) {
155            if (obj == this) {
156                return true;
157            }
158            if (!(obj instanceof QuarterDateFormat)) {
159                return false;
160            }
161            if (!super.equals(obj)) {
162                return false;
163            }
164            QuarterDateFormat that = (QuarterDateFormat) obj;
165            if (!Arrays.equals(this.quarters, that.quarters)) {
166                return false;
167            }
168            return true;
169        }
170        
171    }