getNextBusinessDay(int offset, Date baseDate, int[] excludedDaysOfWeek, String[] excludedDateList)

/**
 * @author Ulrich Krause
 */
package de.eknori.ssjsplus.javascript;
 
import java.text.DateFormat;
import java.text.ParseException;
 
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
 
@SuppressWarnings({ "unchecked", "rawtypes" })
public class BusinessDayCalculator {
  public static final SimpleDateFormat DEFAULT_FORMAT = new SimpleDateFormat(
      "dd/mm/yyyy");
 
  /**
   * Use to find out what date is a certain number of days after a base date,
   * not counting certain days of the week.
   * 
   * @param offset
   *            Number of non-excluded days from the baseDate that the result
   *            date will be
   * @param baseDate
   *            Date to start counting offset from. If specify "null" defaults
   *            to today
   * @param excludedDaysOfWeek
   *            Array of constants from java.util.Calendar object e.g.
   *            Calendar.SUNDAY, which are excluded from counting towards
   *            offset for the result
   * @return The earliest date which is offset days after the baseDate. In
   *         counting towards this result date, any excludedDaysOfWeek are
   *         excluded from counting towards the offset
   */
 
  public static Date getNextBusinessDay(int offset, Date baseDate,
      int[] excludedDaysOfWeek) {
    return getNextBusinessDay(offset, baseDate, excludedDaysOfWeek,
        (Hashtable) null);
  }
 
  /**
   * Use to find out what date is a certain number of days after a base date,
   * not counting certain days of the week and certain dates ( company holiday etc ).
   * 
   * @param offset
   *            Number of non-excluded days from the baseDate that the result
   *            date will be
   * @param baseDate
   *            Date to start counting offset from. If specify "null" defaults
   *            to today
   * @param excludedDaysOfWeek
   *            Array of constants from java.util.Calendar object e.g.
   *            Calendar.SUNDAY, which are excluded from counting towards
   *            offset for the result
   * @param excludedDateList
   *            Array of date strings (formatted as
   *            <CODE>SimpleDateFormat.getDateInstance().format(</CODE>))
   *            which represent specific dates which should be excluded from
   *            the counting of days, such as holidays
   * @return The earliest date which is offset days after the baseDate. In
   *         counting towards this result date, any excludedDaysOfWeek and excludedDates are
   *         excluded from counting towards the offset
   */
 
  public static Date getNextBusinessDay(int offset, Date baseDate,
      int[] excludedDaysOfWeek, String[] excludedDateList) {
    Hashtable excludedDates = new Hashtable();
    if (excludedDateList != null)
      for (int i = 0; i < excludedDateList.length; i++) {
        try {
          excludedDates.put(
              DateFormat.getDateInstance().parse(
                  excludedDateList[i]), "");
        } catch (ParseException err) {
        }
      }
    return getNextBusinessDay(offset, baseDate, excludedDaysOfWeek,
        excludedDates);
  }
 
  /**
   * Use to find out what date is a certain number of days after a base date,
   * not counting certain days.
   * 
   * @param offset
   *            Number of non-excluded days from the baseDate that the result
   *            date will be
   * @param baseDate
   *            Date to start counting offset from. If specify "null" defaults
   *            to today
   * @param excludedDaysOfWeek
   *            Array of constants from java.util.Calendar object e.g.
   *            Calendar.SUNDAY, which are excluded from counting towards
   *            offset for the result
   * @param excludedDateList
   *            Array of date objects which represent specific dates which
   *            should be excluded from the counting of days, such as holidays
   * @return The earliest date which is offset days after the baseDate. In
   *         counting towards this result date, any excludedDaysOfWeek are
   *         excluded from counting towards the offset
   */
 
  public static Date getNextBusinessDay(int offset, Date baseDate,
      int[] excludedDaysOfWeek, Date[] excludedDateList) {
    Hashtable excludedDates = new Hashtable();
    if (excludedDateList != null)
      for (int i = 0; i < excludedDateList.length; i++)
        excludedDates.put(excludedDateList[i], "");
    return getNextBusinessDay(offset, baseDate, excludedDaysOfWeek,
        excludedDates);
  }
 
  /**
   * <P>
   * Use to find out what date is a certain number of days after a base date,
   * not counting certain days.
   * 
   * <P>
   * <b>Primary example:</B> Give me the date which is at least 3 business
   * days from today.
   * <P>
   * <b>Usage for example:</B>
   * <UL>
   * <LI><CODE>offset</CODE> = 3
   * <LI><CODE>baseDate</CODE> = today (i.e. <CODE>new Date()</CODE> )
   * <LI><CODE>excludedDaysOfWeek</CODE> = array with values for Sat and Sun
   * (i.e. <CODE>{ Calendar.SATURDAY, Calendar.SUNDAY }</CODE> )
   * <LI><CODE>excludedDates</CODE> = <CODE>Hashtable</CODE> with elements
   * whose keys are <CODE>java.util.Date</CODE> objects equal to various
   * business holidays not to be counted towards progress
   * </UL>
   * 
   * @param offset
   *            Number of non-excluded days from the baseDate that the result
   *            date will be
   * @param baseDate
   *            Date to start counting offset from. If specify "null,"
   *            defaults to today
   * @param excludedDaysOfWeek
   *            Array of constants from java.util.Calendar object e.g.
   *            Calendar.SUNDAY, which are excluded from counting towards
   *            offset for the result
   * @param excludedDates
   *            Hashtable of java.util.Date objects, which represent specific
   *            dates (12:00am midnight) which should be excluded from
   *            counting towards the offset
   * @return The earliest date which is offset days after the baseDate. In
   *         counting towards this result date, any excludedDaysOfWeek or
   *         specifically excludedDates are excluded from counting towards the
   *         offset
   */
 
  public static Date getNextBusinessDay(int offset, Date baseDate,
      int[] excludedDaysOfWeek, Hashtable excludedDates) {
    int i;
    if (offset < 0)
      return null;
    if (baseDate == null) {
      baseDate = new Date();
    }
    Calendar baseCopy = Calendar.getInstance();
    Calendar baseCal = Calendar.getInstance();
    baseCopy.setTime(baseDate);
    baseCal.clear();
    baseCal.set(baseCopy.get(Calendar.YEAR), baseCopy.get(Calendar.MONTH),
        baseCopy.get(Calendar.DATE));
 
    if (excludedDaysOfWeek == null) {
      excludedDaysOfWeek = new int[0];
    }
    if (excludedDates == null) {
      excludedDates = new Hashtable();
    }
    Hashtable excludedDays = new Hashtable();
    for (i = 0; i < excludedDaysOfWeek.length; i++)
      excludedDays.put(new Integer(excludedDaysOfWeek[i]), "");
 
    while (isExcluded(baseCal, excludedDays, excludedDates)) {
      baseCal.add(Calendar.DATE, 1);
    }
    Calendar resultCal = Calendar.getInstance();
    resultCal.setTime(baseCal.getTime());
 
    int daysPerWeek = resultCal.getMaximum(Calendar.DAY_OF_WEEK);
    int daysPerWeekNotExcluded = daysPerWeek - excludedDays.size();
    int wholeWeeksAway = offset / daysPerWeekNotExcluded;
    int remainingoffset = offset % daysPerWeekNotExcluded;
 
    resultCal.add(Calendar.DATE, wholeWeeksAway * daysPerWeek);
 
    int nExcludedDates = 0;
    Enumeration exclDates = excludedDates.keys();
    while (exclDates.hasMoreElements()) {
      Date nextExclDate = (Date) exclDates.nextElement();
      Calendar nextExclCal = Calendar.getInstance();
      nextExclCal.setTime(nextExclDate);
 
      if ((!excludedDays.containsKey(new Integer(nextExclCal
          .get(Calendar.DAY_OF_WEEK))))
          && (baseCal.before(nextExclCal))
          && (!resultCal.before(nextExclCal))) {
 
        nExcludedDates++;
      }
    }
 
    remainingoffset = remainingoffset + nExcludedDates;
    for (i = 0; i < remainingoffset; i++) {
      do {
        resultCal.add(Calendar.DATE, 1);
      } while (isExcluded(resultCal, excludedDays, excludedDates));
    }
 
    return resultCal.getTime();
  }
 
  /**
   * Tells you if the checkCal day/date is in one of the exclusion lists
   * 
   * @param checkCal
   *            Calendar objects representing the date to check
   * @param excludedDays
   *            Hashtable with Integer keys representing days of the week
   *            which count as excluded. Integer keys are constants from
   *            Calendar class, e.g. Calendar.SUNDAY
   * @param excludedDates
   *            Hashtable with elements with java.util.Date objects as keys
   *            which represent specific dates which should be excluded. Dates
   *            should all be set on 12am midnight for correct comparison.
   * @return True if the checkCal date is one of the days or dates that are to
   *         be excluded, as specified by the excludedDays and excludedDates
   *         parameters
   */
  public static boolean isExcluded(Calendar checkCal, Hashtable excludedDays,
      Hashtable excludedDates) {
    Calendar testCal = Calendar.getInstance();
    testCal.clear();
    testCal.set(checkCal.get(Calendar.YEAR), checkCal.get(Calendar.MONTH),
        checkCal.get(Calendar.DAY_OF_MONTH));
    return ((excludedDays != null && excludedDays.containsKey(new Integer(
        checkCal.get(Calendar.DAY_OF_WEEK)))) || (excludedDates != null && excludedDates
        .containsKey(testCal.getTime())));
  }
 
  public static void main(String[] args) throws ParseException {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy");
    Date baseDate = dateFormat.parse("7.5.2012");
    int[] excludedDays = new int[] { Calendar.SATURDAY, Calendar.SUNDAY };
    String[] excludedDates = new String[] { "08.05.2012", "09.05.2012" };
    Date NBD = getNextBusinessDay(1, baseDate, excludedDays, excludedDates);
 
    System.out.println("getNextBusinessDay: " + NBD);
 
  }
}





使用方法については、コード内のコメントを参照

Java
katoman
August 19, 2015 at 1:47 PM
Rating
0





No comments yetLogin first to comment...