Java tutorial
/* * 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); } }