kr.debop4j.timeperiod.calendars.CalendarDateDiff.java Source code

Java tutorial

Introduction

Here is the source code for kr.debop4j.timeperiod.calendars.CalendarDateDiff.java

Source

/*
 * Copyright 2011-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kr.debop4j.timeperiod.calendars;

import kr.debop4j.timeperiod.*;
import kr.debop4j.timeperiod.timeline.TimeGapCalculator;
import kr.debop4j.timeperiod.tools.TimeSpec;
import kr.debop4j.timeperiod.tools.Times;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Duration;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static kr.debop4j.core.Guard.shouldBe;
import static kr.debop4j.core.Guard.shouldNotBeNull;
import static kr.debop4j.timeperiod.tools.Durations.Zero;
import static kr.debop4j.timeperiod.tools.Durations.negate;
import static kr.debop4j.timeperiod.tools.Times.startTimeOfDay;
import static org.joda.time.Duration.ZERO;

/**
 *  {@link ITimeCalendar}   ??? ({@link org.joda.time.Duration} ? .
 *
 * @author ? sunghyouk.bae@gmail.com
 * @since 13. 5. 21.  9:29
 */
@Slf4j
public class CalendarDateDiff {

    private final CalendarPeriodCollectorFilter collectorFilter = new CalendarPeriodCollectorFilter();
    @Getter
    private final ITimeCalendar calendar;

    public CalendarDateDiff() {
        this(TimeCalendar.getEmptyOffset());
    }

    public CalendarDateDiff(ITimeCalendar calendar) {
        shouldNotBeNull(calendar, "calendar");
        shouldBe(calendar.getStartOffset().isEqual(ZERO),
                "Calendar.StartOffset? Duration.ZERO ? .");
        shouldBe(calendar.getEndOffset().isEqual(ZERO), "Calendar.EndOffset? Duration.ZERO ? .");

        this.calendar = calendar;
    }

    public List<DayOfWeek> getWeekDays() {
        return collectorFilter.getWeekDays();
    }

    public List<HourRangeInDay> getWorkingHours() {
        return this.collectorFilter.getCollectingHours();
    }

    public List<DayHourRange> getWorkingDayHours() {
        return this.collectorFilter.getCollectingDayHours();
    }

    /**  (-)? working day . */
    public void addWorkingDays() {
        addWeekDays(TimeSpec.Weekdays);
    }

    /** ? (-?)? working day . */
    public void addWeekendDays() {
        addWeekDays(TimeSpec.Weekends);
    }

    private void addWeekDays(DayOfWeek... dayOfWeeks) {
        if (getWeekDays() != null)
            Collections.addAll(getWeekDays(), dayOfWeeks);
    }

    /**
     * ? ?  ?? ? .
     *
     * @param moment  ?
     * @return  ? ~  ? ?? Working Hours
     */
    public Duration difference(DateTime moment) {
        return difference(moment, Times.now());
    }

    /**
     *  ? ~  ? ?? ? Working Time? .
     *
     * @param fromTime  ?
     * @param toTime    ?
     * @return  ? ~  ? ?? Working Hours
     */
    public Duration difference(DateTime fromTime, DateTime toTime) {
        if (CalendarDateDiff.log.isTraceEnabled())
            CalendarDateDiff.log.trace("fromTime[{}] ~ toTime[{}]? Working Time? .", fromTime,
                    toTime);

        if (Objects.equals(fromTime, toTime))
            return Zero;

        boolean filterIsEmpty = this.getWeekDays().size() == 0 && this.getWorkingHours().size() == 0
                && this.getWorkingDayHours().size() == 0;

        if (filterIsEmpty) {
            return new DateDiff(fromTime, toTime, getCalendar()).getDifference();
        }

        TimeRange differenceRange = new TimeRange(fromTime, toTime);
        CalendarPeriodCollector collector = new CalendarPeriodCollector(this.collectorFilter,
                new TimeRange(startTimeOfDay(differenceRange.getStart()),
                        startTimeOfDay(differenceRange.getEnd()).plusDays(1)),
                SeekDirection.Forward, getCalendar());
        // Gap? .
        TimeGapCalculator<TimeRange> gapCalculator = new TimeGapCalculator<>(getCalendar());
        ITimePeriodCollection gaps = gapCalculator.getGaps(collector.getPeriods(), differenceRange);
        Duration difference = Zero;
        for (ITimePeriod gap : gaps) {
            difference.plus(gap.getDuration());
        }

        if (CalendarDateDiff.log.isTraceEnabled())
            CalendarDateDiff.log.trace(
                    "fromTime[{}] ~ toTime[{}]? Working Time? . differece=[{}]", fromTime,
                    toTime, difference);

        return (fromTime.compareTo(toTime) <= 0) ? difference : negate(difference);
    }
}