ru.codeinside.calendar.BusinessCalendarDueDateCalculator.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.calendar.BusinessCalendarDueDateCalculator.java

Source

/*
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2014, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.calendar;

import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang.time.DateUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.Set;

/**
 * ?? ? , ?     ?.
 */
final public class BusinessCalendarDueDateCalculator implements DueDateCalculator {

    final Set<Date> workedDays;
    final Set<Date> holidays;

    /**
     * ? ? ? 
     *
     * @param workedDays    
     * @param holidays      
     */
    public BusinessCalendarDueDateCalculator(Set<Date> workedDays, Set<Date> holidays) {
        this.workedDays = ImmutableSet.copyOf(workedDays);
        this.holidays = ImmutableSet.copyOf(holidays);
    }

    @Override
    public Date calculate(Date startDate, int countDays) {
        if (startDate == null)
            throw new IllegalArgumentException(
                    "      NULL");
        if (countDays < 0)
            throw new IllegalArgumentException(
                    "?       ");

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        while (countDays > 0) {
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            if (isWorkedDay(calendar)) {
                countDays--;
            }
        }
        return calendar.getTime();
    }

    /**
     * ?? ?    ? 
     *
     * @param startDate   
     * @param endDate    ? 
     * @return ?    
     */
    @Override
    public int countDays(Date startDate, Date endDate) {
        if (startDate == null)
            throw new IllegalArgumentException(
                    "      NULL");
        if (endDate == null)
            throw new IllegalArgumentException(
                    " ?     NULL");
        boolean inverse = false;
        if (endDate.before(startDate)) {
            Date tmp = endDate;
            endDate = startDate;
            startDate = tmp;
            inverse = true;
        }
        int countDays = 0;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        for (;;) {
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            if (calendar.getTime().after(endDate)) {
                break;
            }
            if (isWorkedDay(calendar)) {
                countDays++;
            }
        }
        return inverse ? -countDays : countDays;
    }

    private boolean isWorkedDay(Calendar calendar) {
        Date date = DateUtils.truncate(calendar.getTime(), Calendar.DAY_OF_MONTH);
        boolean isHoliday = isWeekEnd(calendar) || holidays.contains(date);
        boolean isWorkDay = workedDays.contains(date);
        return !isHoliday || isWorkDay;
    }

    private boolean isWeekEnd(Calendar calendar) {
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        return day == Calendar.SUNDAY || day == Calendar.SATURDAY;
    }
}