gt:         final Period[] periodResult = new Period[result.size()];
context: /*
      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.math.BigDecimal;
  import java.math.MathContext;
  import java.util.ArrayList;
  import java.util.Calendar;
  import java.util.GregorianCalendar;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import nl.strohalm.cyclos.entities.reports.ThroughTimeRange;
  import nl.strohalm.cyclos.entities.settings.LocalSettings;
  
  import nl.strohalm.cyclos.entities.utils.Period;
  import nl.strohalm.cyclos.entities.utils.TimePeriod;
  import org.apache.commons.lang.time.DateUtils;
  
  /**
   * Helper class for dates
   * @author luis
   */
  public class DateHelper {
  
      /**
       * Returns the number of days between 2 dates. Will be negative if date2 &lt; date1, 0 if both are the same day or positive otherwise
       */
      public static int daysBetween(Calendar date1, Calendar date2) {
          if (date1 == null || date2 == null) {
              return 0;
          }
          date1 = truncate(date1);
          date2 = truncate(date2);
          return (int) ((date2.getTimeInMillis() - date1.getTimeInMillis()) / DateUtils.MILLIS_PER_DAY);
      }
  
      /**
       * inverse function of decimalDaysBetween: adds a BigDecimal number of days to a Calendar.
       * @param date1 the date to which something is added
       * @param augend the number of days which is added, as a BigDecimal. May be negative.
       * @return null if one of the arguments is null, else the date + augend days.
       */
      public static Calendar decimalDaysAdd(final Calendar date1, final BigDecimal augend) {
          if (date1 == null || augend == null) {
              return null;
          }
          final BigDecimal date1InMillis = new BigDecimal(date1.getTimeInMillis());
          final BigDecimal augendInMillis = augend.multiply(new BigDecimal(DateUtils.MILLIS_PER_DAY));
          final BigDecimal resultAsBig = date1InMillis.add(augendInMillis);
          final Calendar result = Calendar.getInstance();
          result.setTimeInMillis(resultAsBig.longValue());
          return result;
      }
  
      /**
       * Returns the number of days between 2 dates as a BigDecimal. Will be negative if date2 &lt; date1, or positive otherwise.
       */
      public static BigDecimal decimalDaysBetween(final Calendar date1, final Calendar date2) {
          if (date1 == null || date2 == null) {
              return BigDecimal.ZERO;
          }
          final BigDecimal difference = new BigDecimal(date2.getTimeInMillis() - date1.getTimeInMillis());
          final MathContext mathContext = new MathContext(LocalSettings.MAX_PRECISION);
          final BigDecimal result = difference.divide(new BigDecimal(DateUtils.MILLIS_PER_DAY), mathContext);
          return result;
      }
  
      /**
       * sets the time of the day of the first argument, so that it is equal to the time of the day of the second argument.
       * @param toEqualize a Calendar, whose time will be equalized to the source's time of the day
       * @param source the time of the day of this Calendar is taken.
       * @return a new Calendar object, with the date equal to toEqualize, but the time of the date is equal to that of the source Calendar.
       */
      public static Calendar equalizeTime(final Calendar toEqualize, final Calendar source) {
          if (source == null) {
              return null;
          }
          final int hourOfDay = source.get(Calendar.HOUR_OF_DAY);
          final int minute = source.get(Calendar.MINUTE);
          final int second = source.get(Calendar.SECOND);
          final int milliSecond = source.get(Calendar.MILLISECOND);
          final Calendar result = (Calendar) toEqualize.clone();
          result.set(Calendar.HOUR_OF_DAY, hourOfDay);
          result.set(Calendar.MINUTE, minute);
          result.set(Calendar.SECOND, second);
          result.set(Calendar.MILLISECOND, milliSecond);
          return result;
      }
  
      /**
       * compares two Calendars on a certain precision level. <br>
       * For example, if you had the datetime of 12 Mar 2011 14:31:07.847, and a second datetime of 12 Mar 2011 14:31:11.734, they would evaluate as
       * equal on the Calendar.MINUTE level and above. They would evaluate as not equal on levels Calendar.SECOND and Calendar.MILLISECOND.<br>
       * Fields are rounded, so 12 Mar 2011 14:31:07.847 and 12 Mar 2011 14:31:08.123 would evaluate as equal on the Calendar.SECOND level.
       * @param cal1 if null, returns false
       * @param cal2 if null, returns false
       * @param level, for example Calendar.MINUTE
       * @return true if equal on this level, false if not.
       */
      public static boolean equals(final Calendar cal1, final Calendar cal2, final int level) {
          if (cal1 == null || cal2 == null) {
              return false;
          }
          final Calendar temp1 = DateUtils.round((Calendar) cal1.clone(), level);
          final Calendar temp2 = DateUtils.round((Calendar) cal2.clone(), level);
          return (temp1.equals(temp2));
      }
  
      /**
       * Returns a date at 23:59:59 of the given day
       */
      public static Calendar getDayEnd(final Calendar date) {
          return TimePeriod.ONE_DAY.currentPeriod(date).getEnd();
      }
  
      /**
       * a null proof method returning the earliest of any number of Calendars
       * @param dates any null arguments are ignored. If all arguments are null just returns null.
       * @return the earliest date of the arguments.
       */
      public static Calendar getEarliest(final Calendar... dates) {
          Calendar oldest = null;
          for (final Calendar date : dates) {
              if (oldest == null || (date != null && oldest.after(date))) {
                  oldest = date;
              }
          }
          return oldest;
      }
  
      public static Map<String, Object> getLastCompletedMonthAndYear() {
          final Calendar now = Calendar.getInstance();
          int month = now.get(Calendar.MONTH);
          int year = now.get(Calendar.YEAR);
          if (month == 0) {
              month = 12;
              year--;
          } else {
              month--;
          }
          final Map<String, Object> completedMonthAndYear = new HashMap<String, Object>();
          completedMonthAndYear.put("month", month);
          completedMonthAndYear.put("year", year);
          return completedMonthAndYear;
      }
  
      public static Map<String, Object> getLastCompletedQuarterAndYear() {
          final Calendar now = Calendar.getInstance();
          final int month = now.get(Calendar.MONTH);
          int year = now.get(Calendar.YEAR);
          Quarter quarter = null;
          switch (month) {
              case 0:
              case 1:
              case 2:
                  quarter = Quarter.FOURTH;
                  year--;
                  break;
              case 3:
              case 4:
              case 5:
                  quarter = Quarter.FIRST;
                  break;
              case 6:
              case 7:
              case 8:
                  quarter = Quarter.SECOND;
                  break;
              case 9:
              case 10:
              case 11:
                  quarter = Quarter.THIRD;
                  break;
          }
          final Map<String, Object> completedQuarterAndYear = new HashMap<String, Object>();
          completedQuarterAndYear.put("quarter", quarter);
          completedQuarterAndYear.put("year", year);
          return completedQuarterAndYear;
      }
  
      public static Period[] getPeriodsThroughTheTime(final Period period, final ThroughTimeRange throughTimeRange) {
          final Calendar calendarIni = period.getBegin();
          final Calendar calendarFini = period.getEnd();
          final List<Period> result = new ArrayList<Period>();
  
          final int monthIni = calendarIni.get(Calendar.MONTH);
          final int monthFini = calendarFini.get(Calendar.MONTH);
          final int yearIni = calendarIni.get(Calendar.YEAR);
          final int yearFini = calendarFini.get(Calendar.YEAR);
  
          for (int year = calendarIni.get(Calendar.YEAR); year <= calendarFini.get(Calendar.YEAR); year++) {
              Period periodAux = null;
              int monthIniAux = 0;
              int monthFiniAux = 11;
  
              if (year == yearIni) {
                  monthIniAux = monthIni;
              } else {
                  monthIniAux = 0;
              }
  
              if (year == yearFini) {
                  monthFiniAux = monthFini;
              } else {
                  monthFiniAux = 11;
              }
              int increment = 1;
  
              // months or quarters
              if (throughTimeRange == ThroughTimeRange.MONTH || throughTimeRange == ThroughTimeRange.QUARTER) {
                  // only quarters
                  if (throughTimeRange == ThroughTimeRange.QUARTER) {
                      increment = 3;
                  }
                  for (int month = monthIniAux; month <= monthFiniAux; month = month + increment) {
                      final Calendar calendarIniAux = new GregorianCalendar(year, month, 1, 0, 0, 0);
                      final Calendar calendarFiniHlp = new GregorianCalendar(year, (month + increment - 1), 1);
                      final Calendar calendarFiniAux = new GregorianCalendar(year, (month + increment - 1), calendarFiniHlp.getActualMaximum(Calendar.DAY_OF_MONTH), 23, 59, 59);
                      periodAux = new Period(calendarIniAux, calendarFiniAux);
                      result.add(periodAux);
                  }
              }
              // years, it doesn't need to iterate over months.
              else if (throughTimeRange == ThroughTimeRange.YEAR) {
                  final Calendar calendarIniAux = new GregorianCalendar(year, 0, 1, 0, 0, 0);
                  final Calendar calendarFiniAux = new GregorianCalendar(year, 11, 31, 23, 59, 59);
                  periodAux = new Period(calendarIniAux, calendarFiniAux);
                  result.add(periodAux);
              }
          }
  