/* 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>"); } }