nl.strohalm.cyclos.utils.NamedPeriod.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.utils.NamedPeriod.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.utils;

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * A date period which can be given a name (currently used in stats, where two periods are compared). Inherits most of its functionality directly from
 * Period.
 * @author rinke
 */
public class NamedPeriod extends Period {

    private static final long serialVersionUID = 474875095971518438L;

    /**
     * takes today, and calculates which quarter is the last one which has been completed. example: if today is 14 octobre, the last completed quarter
     * of the year is july to september, so the method returns a 3.
     * @return int quarter, being 1, 2, 3 or 4, for jan-march, april-june, july-sept and oct-dec.
     */
    public static int getLastQuarter() {
        final Calendar today = Calendar.getInstance();
        return getLastQuarter(today);
    }

    /**
     * See getLastQuarter() without a parameter. This version does not take today as starting point, but an arbitrary date, which is fed as a
     * parameter
     * @param cal : the date for which you want to know the last completed quarter of the year
     * @return the number of the quarter being 1, 2, 3 or 4, for jan-march, april-june, july-sept and oct-dec.
     */
    public static int getLastQuarter(final Calendar cal) {
        final int month = cal.get(Calendar.MONTH);
        final int quarter = (month / 3) + 1;
        return quarter;
    }

    /**
     * @see #getQuarterPeriod(Calendar)
     * @return a quarterly period, the last one falling before today
     */
    public static NamedPeriod getLastQuarterPeriod() {
        final Calendar today = Calendar.getInstance();
        return NamedPeriod.getQuarterPeriod(today);
    }

    /**
     * Makes a defaultperiod for the form. It calculates the last quarter which was finished via the getLastQuarter() method. Then it calculates the
     * starting and ending day for this period. However, if the needed quarter is the last of a year, then it returns a whole year, in stead of a
     * whole quarter. In this case, the enddate is the same as it would have been with the quarter. The name of the Period is generated via the
     * produceName method
     * @param aDate returns the last completed quarter which falls before this date. So if this date is january 1st, the method returns quarter 4 of
     * the previous year (octobre 1st to decembre 31st)
     * @return a quarterly period
     * @see #getLastQuarter()
     * @see #produceName(int, int)
     */
    public static NamedPeriod getQuarterPeriod(final Calendar aDate) {
        int year = aDate.get(Calendar.YEAR);
        final int quarter = getLastQuarter(aDate);
        final int endMonth = (3 * quarter) - 3;
        final Calendar endDay = new GregorianCalendar(year, endMonth, 1, 0, 0, 0);
        final Calendar startDay = (Calendar) endDay.clone();
        if (quarter == 1) {
            startDay.add(Calendar.YEAR, -1);
            year--;
        } else {
            startDay.add(Calendar.MONTH, -3);
        }
        endDay.add(Calendar.MILLISECOND, -1); // do not include the endday, by distracting one millisecond from the first of next month
        final NamedPeriod period = new NamedPeriod(startDay, endDay, produceName(year, quarter));
        return period;
    }

    /**
     * makes a name, based on the year and the quarter (so: "1997 II" for example). In the last quarter, the default period is a whole year, so then
     * it will be just "1997"
     * @param year
     * @param quarter
     * @return the name for the NamedPeriod
     */
    private static String produceName(final int year, final int quarter) {
        String name = "";
        for (int i = quarter - 1; i > 0; i--) {
            name = name + "I";
        }
        name = ("" + year + " " + name).trim();
        return name;
    }

    /**
     * name of the Period, to be displayed in the result jsp
     */
    private String name;

    /**
     * default constructor
     * 
     */
    public NamedPeriod() {
        super();
    }

    /**
     * constructor with begin and end date
     * @param begin the start date of the period
     * @param end the end date of the period
     */
    public NamedPeriod(final Calendar begin, final Calendar end) {
        super(begin, end);
    }

    /**
     * constructor with begin and enddate, plus a name
     * @param begin the start date of the period
     * @param end the end date of the period
     * @param name the name of the period
     */
    public NamedPeriod(final Calendar begin, final Calendar end, final String name) {
        this(begin, end);
        this.name = name;
    }

    @Override
    public boolean equals(final Object obj) {
        if (!(obj instanceof NamedPeriod)) {
            return false;
        }
        final NamedPeriod p = (NamedPeriod) obj;
        return new EqualsBuilder().append(getBegin(), p.getBegin()).append(getEnd(), p.getEnd()).isEquals();
    };

    public String getName() {
        return name;
    }

    /**
     * @return a new NamedPeriod, exactly one year earlier than the present period If the 4 digit year is part of the name, then the substring
     * representing the year is adapted to the previous year. Otherwise, the name is just copied.
     */
    public NamedPeriod getOneYearEarlier() {
        final Calendar beginDate = (Calendar) getBegin().clone();
        beginDate.add(Calendar.YEAR, -1);
        final Calendar endDate = (Calendar) getEnd().clone();
        endDate.add(Calendar.YEAR, -1);
        final int presentYear = getBegin().get(Calendar.YEAR);
        String newName = getName();
        if (getName().indexOf(String.valueOf(presentYear)) >= 0) {
            newName = getName().replaceAll(String.valueOf(presentYear), String.valueOf(presentYear - 1));
        }
        return new NamedPeriod(beginDate, endDate, newName);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(getBegin()).append(getEnd()).toHashCode();
    }

    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return super.toString() + ", name: " + FormatObject.formatObject(name, "<null>");
    }

}