package se.idega.idegaweb.commune.accounting.invoice.business; import se.idega.idegaweb.commune.accounting.business.AccountingUtil; import com.idega.util.IWTimestamp; /** * Holder for times that are calculated for placement times * * @author Joakim * */ public class PlacementTimes { private final IWTimestamp firstCheckDay; private final IWTimestamp lastCheckDay; private final int specificNumberOfDaysPrMonth; public PlacementTimes(final IWTimestamp firstCheckDay, final IWTimestamp lastCheckDay, int specificNumberOfDays) { this.firstCheckDay = firstCheckDay; this.lastCheckDay = lastCheckDay; specificNumberOfDaysPrMonth = specificNumberOfDays; } public int getDays() { return 1 + AccountingUtil.getDayDiff(firstCheckDay, lastCheckDay); } public float getMonths() { if (isWholeNumberOfMonths()) { return getNumberOfMonths(daysInMonth(firstCheckDay), daysInMonth(lastCheckDay)); } int daysInMonthFirstCheckDay = (specificNumberOfDaysPrMonth > 0) ? specificNumberOfDaysPrMonth : daysInMonth(firstCheckDay); int daysInMonthLastCheckDay = (specificNumberOfDaysPrMonth > 0) ? specificNumberOfDaysPrMonth : daysInMonth(lastCheckDay); return getNumberOfMonths(daysInMonthFirstCheckDay, daysInMonthLastCheckDay); } public IWTimestamp getLastCheckDay() { return lastCheckDay; } public IWTimestamp getFirstCheckDay() { return firstCheckDay; } private float getNumberOfMonths(int daysInMonthFirstCheckDay, int daysInMonthLastCheckDay) { float months = 1.0f + (lastCheckDay.getYear() * 12 + lastCheckDay.getMonth()) - (firstCheckDay.getYear() * 12 + firstCheckDay.getMonth()); // decrease with days before start date months -= (float) (firstCheckDay.getDay() - 1) / (float) daysInMonthFirstCheckDay; // decrease with days after end date months -= 1.0f - (float) lastCheckDay.getDay() / (float) daysInMonthLastCheckDay; return months; } /* * A method that checks if the number of days between the two check dates is * a whole number of months. Will return true if the difference between the * dates + 1 is 0 or is equal to the number of days in the first month (this * is true if we are handling only one month or multiple months, but the * start date is not the 1st and the end date is not the last day of that * month). Will alse return true if the first date is the 1st of some month * and the last date is the last day of some other month. * */ private boolean isWholeNumberOfMonths() { int days = lastCheckDay.getDay() - firstCheckDay.getDay() + 1; if (days == 0 || days == daysInMonth(firstCheckDay)) { return true; } if (firstCheckDay.getDay() == 1 && (lastCheckDay.getDay() == daysInMonth(lastCheckDay))) { return true; } return false; } private int daysInMonth(final IWTimestamp date) { final IWTimestamp firstDay = new IWTimestamp(date); firstDay.setDay(1); final IWTimestamp lastDay = new IWTimestamp(firstDay); lastDay.addMonths(1); final int daysInMonth = AccountingUtil.getDayDiff(firstDay, lastDay); return daysInMonth; } }