/*
* file: TimescaleUtility.java
* author: Jon Iles
* copyright: (c) Packwood Software 2011
* date: 2011-02-12
*/
/*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
package net.sf.mpxj.utility;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import net.sf.mpxj.DateRange;
import net.sf.mpxj.mpp.TimescaleUnits;
/**
* This class contains methods related to creation of timescale data.
*/
public final class TimescaleUtility
{
/**
* Given a start date, a timescale unit, and a number of segments, this
* method creates an array of date ranges. For example, if "Months" is
* selected as the timescale units, this method will create an array of
* ranges, each one representing a month. The number of entries in the
* array is determined by the segment count.
*
* Each of these date ranges is equivalent one of the columns displayed by
* MS Project when viewing data with a "timescale" at the top of the page.
*
* @param startDate start date
* @param segmentUnit units to be represented by each segment (column)
* @param segmentCount number of segments (columns) required
* @return array of date ranges
*/
public final ArrayList<DateRange> createTimescale(Date startDate, TimescaleUnits segmentUnit, int segmentCount)
{
ArrayList<DateRange> result = new ArrayList<DateRange>(segmentCount);
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
int calendarIncrementUnit;
int calendarIncrementAmount;
switch (segmentUnit)
{
case MINUTES:
{
calendarIncrementUnit = Calendar.MINUTE;
calendarIncrementAmount = 1;
break;
}
case HOURS:
{
calendarIncrementUnit = Calendar.HOUR_OF_DAY;
calendarIncrementAmount = 1;
break;
}
case WEEKS:
{
cal.set(Calendar.DAY_OF_WEEK, m_weekStartDay);
calendarIncrementUnit = Calendar.DAY_OF_YEAR;
calendarIncrementAmount = 7;
break;
}
case THIRDS_OF_MONTHS:
{
cal.set(Calendar.DAY_OF_MONTH, 1);
calendarIncrementUnit = Calendar.DAY_OF_YEAR;
calendarIncrementAmount = 10;
break;
}
case MONTHS:
{
cal.set(Calendar.DAY_OF_MONTH, 1);
calendarIncrementUnit = Calendar.MONTH;
calendarIncrementAmount = 1;
break;
}
case QUARTERS:
{
int currentMonth = cal.get(Calendar.MONTH);
int currentQuarter = currentMonth / 3;
int startMonth = currentQuarter * 3;
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, startMonth);
calendarIncrementUnit = Calendar.MONTH;
calendarIncrementAmount = 3;
break;
}
case HALF_YEARS: // align to jan, jun
{
int currentMonth = cal.get(Calendar.MONTH);
int currentHalf = currentMonth / 6;
int startMonth = currentHalf * 6;
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, startMonth);
calendarIncrementUnit = Calendar.MONTH;
calendarIncrementAmount = 6;
break;
}
case YEARS: // align to 1 jan
{
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, Calendar.JANUARY);
calendarIncrementUnit = Calendar.YEAR;
calendarIncrementAmount = 1;
break;
}
default:
case DAYS:
{
calendarIncrementUnit = Calendar.DAY_OF_YEAR;
calendarIncrementAmount = 1;
break;
}
}
for (int loop = 0; loop < segmentCount; loop++)
{
Date rangeStart = cal.getTime();
if (segmentUnit == TimescaleUnits.THIRDS_OF_MONTHS && (loop + 1) % 3 == 0)
{
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, 1);
}
else
{
cal.add(calendarIncrementUnit, calendarIncrementAmount);
}
cal.add(Calendar.MILLISECOND, -1);
result.add(new DateRange(rangeStart, cal.getTime()));
cal.add(Calendar.MILLISECOND, 1);
}
return result;
}
/**
* Set the day on which the week starts. Defaults to Calendar.MONDAY.
*
* @param weekStartDay week start day
*/
public void setWeekStartDay(int weekStartDay)
{
m_weekStartDay = weekStartDay;
}
/**
* Retrieves the day on which the week starts.
*
* @return week start day
*/
public int getWeekStartDay()
{
return m_weekStartDay;
}
private int m_weekStartDay = Calendar.MONDAY;
}