package se.idega.idegaweb.commune.accounting.business; import com.idega.util.IWTimestamp; import java.util.Date; import java.util.Calendar; import java.util.GregorianCalendar; /** * Last modified: $Date: 2004/03/10 10:53:28 $ by $Author: staffan $ * * @author <a href="http://www.staffannoteberg.com">Staffan N�teberg</a> * @version $Revision: 1.5 $ */ public class AccountingUtil { public static long roundAmount (float f) { final long round = Math.round (f); return round - (0.5f == f - Math.floor (f) ? (round % 2) : 0); } /** * See documentation for: getDayDiff (Calendar, Calendar) */ public static int getDayDiff (final Date startDate, final Date endDate) { final Calendar startCalendar = new GregorianCalendar (); startCalendar.setTime (startDate); final Calendar endCalendar = new GregorianCalendar (); endCalendar.setTime (endDate); return getDayDiff (startCalendar, endCalendar); } /** * See documentation for: getDayDiff (Calendar, Calendar) */ public static int getDayDiff (final IWTimestamp startStamp, final IWTimestamp endStamp) { final Calendar startCalendar = new GregorianCalendar (); startCalendar.setTime (startStamp.getDate ()); final Calendar endCalendar = new GregorianCalendar (); endCalendar.setTime (endStamp.getDate ()); return getDayDiff (startCalendar, endCalendar); } /** * Evaluates the difference in days between to dates. This method is aware of * some obstacles, otherwise easy forgotten: * <ul> * <li> Daylight saving effects - days could be 23, 24 or 25 hours</li> * <li> Leap years - years could be 365 or 366 days</li> * <li> Time differences in dates - there's one day between 23:55:55 and * 00:05:05 next day, even though only 10 minutes have passed</li> * <li> Negative intervals - if endCalendar is before startCalendar, then a * negative result will be returned</li> * <li> Intervals spanning over new years</li> * </ul> * <p/> * See examples below to understand the algorithm: * <pre> * 2003-dec-31 : 2004-jan-01 = 1 * 2004-mar-11 : 2004-mar-31 = 20 * 2003-dec-31 : 2005-jan-01 = 367 * 2004-jan-01 : 2003-dec-31 = -1 * 2004-jan-01 : 2004-jan-01 = 0 * 2002-dec-31 : 2004-jan-01 = 366 * </pre> * * @param startCalendar the first day of the interval * @param endCalendar the last day of the interval * @return subtracted value between day numbers - positive, zero or negative */ public static int getDayDiff (final Calendar startCalendar, final Calendar endCalendar) { final int startYear = startCalendar.get (Calendar.YEAR); final int endYear = endCalendar.get (Calendar.YEAR); final int yearBasedOffset = getYearBasedOffset (startYear, endYear); final int startDay = startCalendar.get (Calendar.DAY_OF_YEAR); final int endDay = endCalendar.get (Calendar.DAY_OF_YEAR) + yearBasedOffset; return endDay - startDay; } /** * Gets the offset in days between to different years, i.e. the number of * days in each year in which new year limit is in the interval. This method * is aware of leap years. * <p/> * See examples below to understand the algorithm: * <pre> * 2003 : 2004 = 365 * 2004 : 2004 = 0 * 2003 : 2005 = 731 * 2004 : 2003 = -365 * 2004 : 2004 = 0 * 2002 : 2004 = 730 * </pre> * * @param startYear the first year of the interval * @param endYear the last year of the interval * @return offset in days in the interval */ private static int getYearBasedOffset (final int startYear, final int endYear) { final int result; if (startYear < endYear) { final Calendar calendar = new GregorianCalendar (startYear, 0, 1); result = calendar.getActualMaximum (Calendar.DAY_OF_YEAR) + getYearBasedOffset (startYear + 1, endYear); } else if (startYear > endYear) { result = -getYearBasedOffset (endYear, startYear); } else { result = 0; } return result; } /** * This main is only for testing. It's never invoked in IdegaWeb. */ public static void main (final String[] arg) { final Calendar c1 = new GregorianCalendar (2004, 0, 1); final Calendar c2 = new GregorianCalendar (2003, 11, 31); final Calendar c3 = new GregorianCalendar (2004, 2, 11); final Calendar c4 = new GregorianCalendar (2004, 2, 31); final Calendar c5 = new GregorianCalendar (2005, 0, 1); final Calendar c6 = new GregorianCalendar (2002, 11, 31); final java.text.DateFormat df = java.text.DateFormat.getDateInstance (); // testing getDayDiff System.out.println (df.format (new Date (c2.getTimeInMillis())) + " : " + df.format (new Date (c1.getTimeInMillis ())) + " = " + getDayDiff (c2, c1)); System.out.println (df.format (new Date (c3.getTimeInMillis())) + " : " + df.format (new Date (c4.getTimeInMillis())) + " = " + getDayDiff (c3, c4)); System.out.println (df.format (new Date (c2.getTimeInMillis())) + " : " + df.format (new Date (c5.getTimeInMillis())) + " = " + getDayDiff (c2, c5)); System.out.println (df.format (new Date (c1.getTimeInMillis())) + " : " + df.format (new Date (c2.getTimeInMillis())) + " = " + getDayDiff (c1, c2)); System.out.println (df.format (new Date (c1.getTimeInMillis())) + " : " + df.format (new Date (c1.getTimeInMillis())) + " = " + getDayDiff (c1, c1)); System.out.println (df.format (new Date (c6.getTimeInMillis())) + " : " + df.format (new Date (c1.getTimeInMillis())) + " = " + getDayDiff (c6, c1)); // testing getYearBasedOffset System.out.println (2003 + " : " + 2004 + " = " + getYearBasedOffset (2003, 2004)); System.out.println (2004 + " : " + 2004 + " = " + getYearBasedOffset (2004, 2004)); System.out.println (2003 + " : " + 2005 + " = " + getYearBasedOffset (2003, 2005)); System.out.println (2004 + " : " + 2003 + " = " + getYearBasedOffset (2004, 2003)); System.out.println (2004 + " : " + 2004 + " = " + getYearBasedOffset (2004, 2004)); System.out.println (2002 + " : " + 2004 + " = " + getYearBasedOffset (2002, 2004)); } }