    001/* ===========================================================
    002 * JFreeChart : a free chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C) Copyright 2000-2011, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    025 * Other names may be trademarks of their respective owners.]
    026 *
    027 * ----------------------
    028 * QuarterDateFormat.java
    029 * ----------------------
    030 * (C) Copyright 2005-2008, by Object Refinery Limited and Contributors.
    031 *
    032 * Original Author:  David Gilbert (for Object Refinery Limited);
    033 * Contributor(s):   -;
    034 *
    035 * Changes:
    036 * --------
    037 * 01-Mar-2005 : Version 1 (DG);
    038 * 10-May-2005 : Added equals() method, and implemented Cloneable and
    039 *               Serializable (DG);
    040 * ------------- JFREECHART 1.0.x ---------------------------------------------
    041 * 08-Jun-2007 : Added Greek symbols, and support for reversing the date - see
    042 *               patch 1577221 (DG);
    043 *
    044 */
    045
    046package org.jfree.chart.axis;
    047
    048import java.io.Serializable;
    049import java.text.DateFormat;
    050import java.text.FieldPosition;
    051import java.text.NumberFormat;
    052import java.text.ParsePosition;
    053import java.util.Arrays;
    054import java.util.Calendar;
    055import java.util.Date;
    056import java.util.GregorianCalendar;
    057import java.util.TimeZone;
    058
    059/**
    060 * A formatter that formats dates to show the year and quarter (for example,
    061 * '2004 IV' for the last quarter of 2004.
    062 */
    063public class QuarterDateFormat extends DateFormat
    064        implements Cloneable, Serializable {
    065
    066    /** For serialization. */
    067    private static final long serialVersionUID = -6738465248529797176L;
    068
    069    /** Symbols for regular quarters. */
    070    public static final String[] REGULAR_QUARTERS = new String[] {"1", "2",
    071            "3", "4"};
    072
    073    /** Symbols for roman numbered quarters. */
    074    public static final String[] ROMAN_QUARTERS  = new String[] {"I", "II",
    075            "III", "IV"};
    076
    077    /**
    078     * Symbols for greek numbered quarters.
    079     *
    080     * @since 1.0.6
    081     */
    082    public static final String[] GREEK_QUARTERS = new String[] {"\u0391",
    083            "\u0392", "\u0393", "\u0394"};
    084
    085    /** The strings. */
    086    private String[] quarters = REGULAR_QUARTERS;
    087
    088    /** A flag that controls whether the quarter or the year goes first. */
    089    private boolean quarterFirst;
    090
    091    /**
    092     * Creates a new instance for the default time zone.
    093     */
    094    public QuarterDateFormat() {
    095        this(TimeZone.getDefault());
    096    }
    097
    098    /**
    099     * Creates a new instance for the specified time zone.
    100     *
    101     * @param zone  the time zone (<code>null</code> not permitted).
    102     */
    103    public QuarterDateFormat(TimeZone zone) {
    104        this(zone, REGULAR_QUARTERS);
    105    }
    106
    107    /**
    108     * Creates a new instance for the specified time zone.
    109     *
    110     * @param zone  the time zone (<code>null</code> not permitted).
    111     * @param quarterSymbols  the quarter symbols.
    112     */
    113    public QuarterDateFormat(TimeZone zone, String[] quarterSymbols) {
    114        this(zone, quarterSymbols, false);
    115    }
    116
    117    /**
    118     * Creates a new instance for the specified time zone.
    119     *
    120     * @param zone  the time zone (<code>null</code> not permitted).
    121     * @param quarterSymbols  the quarter symbols.
    122     * @param quarterFirst  a flag that controls whether the quarter or the
    123     *         year is displayed first.
    124     *
    125     * @since 1.0.6
    126     */
    127    public QuarterDateFormat(TimeZone zone, String[] quarterSymbols,
    128            boolean quarterFirst) {
    129        if (zone == null) {
    130            throw new IllegalArgumentException("Null 'zone' argument.");
    131        }
    132        this.calendar = new GregorianCalendar(zone);
    133        this.quarters = quarterSymbols;
    134        this.quarterFirst = quarterFirst;
    135
    136        // the following is never used, but it seems that DateFormat requires
    137        // it to be non-null.  It isn't well covered in the spec, refer to
    138        // bug parade 5061189 for more info.
    139        this.numberFormat = NumberFormat.getNumberInstance();
    140
    141    }
    142
    143    /**
    144     * Formats the given date.
    145     *
    146     * @param date  the date.
    147     * @param toAppendTo  the string buffer.
    148     * @param fieldPosition  the field position.
    149     *
    150     * @return The formatted date.
    151     */
    152    public StringBuffer format(Date date, StringBuffer toAppendTo,
    153                               FieldPosition fieldPosition) {
    154        this.calendar.setTime(date);
    155        int year = this.calendar.get(Calendar.YEAR);
    156        int month = this.calendar.get(Calendar.MONTH);
    157        int quarter = month / 3;
    158        if (this.quarterFirst) {
    159            toAppendTo.append(this.quarters[quarter]);
    160            toAppendTo.append(" ");
    161            toAppendTo.append(year);
    162        }
    163        else {
    164            toAppendTo.append(year);
    165            toAppendTo.append(" ");
    166            toAppendTo.append(this.quarters[quarter]);
    167        }
    168        return toAppendTo;
    169    }
    170
    171    /**
    172     * Parses the given string (not implemented).
    173     *
    174     * @param source  the date string.
    175     * @param pos  the parse position.
    176     *
    177     * @return <code>null</code>, as this method has not been implemented.
    178     */
    179    public Date parse(String source, ParsePosition pos) {
    180        return null;
    181    }
    182
    183    /**
    184     * Tests this formatter for equality with an arbitrary object.
    185     *
    186     * @param obj  the object (<code>null</code> permitted).
    187     *
    188     * @return A boolean.
    189     */
    190    public boolean equals(Object obj) {
    191        if (obj == this) {
    192            return true;
    193        }
    194        if (!(obj instanceof QuarterDateFormat)) {
    195            return false;
    196        }
    197        QuarterDateFormat that = (QuarterDateFormat) obj;
    198        if (!Arrays.equals(this.quarters, that.quarters)) {
    199            return false;
    200        }
    201        if (this.quarterFirst != that.quarterFirst) {
    202            return false;
    203        }
    204        return super.equals(obj);
    205    }
    206
    207}