package schedframe.scheduling.plugin.local; import java.util.ArrayList; import org.joda.time.DateTime; /** * @author Ariel Oleksiak * */ public class TimeOperations { long timeDelta; public static final long TWENTY_FOUR_HOURS = 24*60*60*1000; //24h in millis /** * Constructor of DateOperations class * @param timeDelta - parameter used to express potential time overheads, e.g. * while checking if certain period fits into another */ public TimeOperations(long timeDelta) { this.timeDelta = timeDelta; } //Getters/setters public long getTimeDelta() { return timeDelta; } public void setTimeDelta(long timeDelta) { this.timeDelta = timeDelta; } //end of getters/setters //Comparisons /** * Compares two Calendar objects taking into account date only, i.e. * year, month, and day (without hour, minute, second, milis) * @param date1 * @param date2 * @return true if date1 is before date2; false otherwise */ public boolean beforeDate(DateTime date1, DateTime date2) { if (date1 == null || date2 == null) return false; if (date1.getYear() < date2.getYear()) return true; if (date1.getYear() > date2.getYear()) return false; if (date1.getMonthOfYear() < date2.getMonthOfYear()) return true; if (date1.getMonthOfYear() > date2.getMonthOfYear()) return false; if (date1.getDayOfMonth() < date2.getDayOfMonth()) return true; if (date1.getDayOfMonth() > date2.getDayOfMonth()) return false; return false; } /** * Compares two Calendar objects taking into account date only, i.e. * year, month, and day (without hour, minute, second, milis) * @param date1 * @param date2 * @return true if dates are equal; false otherwise */ public boolean sameDate(DateTime date1, DateTime date2) { if (date1 == null || date2 == null) return false; if (date1.getYear() != date2.getYear()) return false; if (date1.getMonthOfYear() != date2.getMonthOfYear()) return false; if (date1.getDayOfMonth() != date2.getDayOfMonth()) return false; return true; } /** * Check whether one date is before another date. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date1 * @param date2 * @return true if date1 is before date2 */ public boolean beforeDayTime(DateTime date1, DateTime date2) { if (date1 == null || date2 == null) return false; if(date1.getHourOfDay() < date2.getHourOfDay()) return true; if(date1.getHourOfDay() > date2.getHourOfDay()) return false; if(date1.getMinuteOfHour() < date2.getMinuteOfHour()) return true; if(date1.getMinuteOfHour() > date2.getMinuteOfHour()) return false; if(date1.getSecondOfMinute() < date2.getSecondOfMinute()) return true; if(date1.getSecondOfMinute() > date2.getSecondOfMinute()) return false; if(date1.getMillisOfSecond() < date2.getMillisOfSecond()) return true; if(date1.getMillisOfSecond() > date2.getMillisOfSecond()) return false; return false; } /** * Check whether a period, whose length is equal duration, is before specific date. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date1 * @param duration - duration of a period to be checked * @param date2 * @return true if date1 + duration is before date2 */ public boolean beforeDayTime(DateTime date1, long duration, DateTime date2) { if (date1 == null || date2 == null) return false; date1 = date1.plus(duration + timeDelta); return beforeDate(date1, date2); } /** * Check whether dates are equal. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date1 * @param date2 * @return true if dates are equal */ public boolean sameDayTime(DateTime date1, DateTime date2) { if (date1 == null || date2 == null) return false; if (date1.getMillisOfDay() != date2.getMillisOfDay()) return false; return true; } /** * Check whether a period, whose length is equal duration, is after specific date. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date1 * @param date2 * @return true if date1 is after date2 */ public boolean afterDayTime(DateTime date1, DateTime date2) { return beforeDayTime(date2, date1); } /** * Check whether a period, whose length is equal duration, is after specific date. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date1 * @param duration - duration of a period to be checked * @param date2 * @return true if date1 + duration is after date2 */ public boolean afterDayTime(DateTime date1, long duration, DateTime date2) { if (date1 == null || date2 == null) return false; date1 = date1.plus(duration + timeDelta); return afterDayTime(date1, date2); } //end of comparisons //Operations on date and time /** * Copy date from newDate DateTime object into date DateTime object. * Time (hour, minutes, seconds, milis) is not copied. * @return DateTime object representing new date */ public DateTime setDate(DateTime date, DateTime newDate) { if (date == null || newDate == null) return date; return new DateTime(newDate.getYear(), newDate.getMonthOfYear(), newDate.getDayOfMonth(), date.getHourOfDay(), date.getMinuteOfHour(), date.getSecondOfMinute(), date.getMillisOfSecond()); } /** * Set time within a day from newTime Calendar object into date Calendar object. * Date (year, month, day) is not set. * @return Calendar object representing new time */ public DateTime setDayTime(DateTime date, DateTime newTime) { if (date == null || newTime == null) return date; return new DateTime(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(), newTime.getHourOfDay(), newTime.getMinuteOfHour(), newTime.getSecondOfMinute(), newTime.getMillisOfSecond()); } //end of operations on date and time //Operations on periods /** * Calculate period duration in milis * @param start * @param end * @return period duration in milis */ public long periodDuration(DateTime start, DateTime end) { if (start == null || end == null) return 0; return end.getMillis() - start.getMillis(); } /** * Calculate period duration in milis taking into account time only, i.e. * hour, minute, second, milis (without year, month, and day) * @param start * @param end * @return period duration in milis */ public long periodDayTimeDuration(DateTime start, DateTime end) { if (start == null && end == null) return TWENTY_FOUR_HOURS; if (start == null) { start = new DateTime(end.getYear(), end.getMonthOfYear(), end.getDayOfMonth(), 0, 0, 0, 0); } if (end == null) { end = new DateTime(start.getYear(), start.getMonthOfYear(), start.getDayOfMonth(), 23, 59, 59, 999); } //setting the same date DateTime newEnd = new DateTime(start.getYear(), start.getMonthOfYear(), start.getDayOfMonth(), end.getHourOfDay(), end.getMinuteOfHour(), end.getSecondOfMinute(), end.getMillisOfSecond() ); if (beforeDayTime(start, newEnd)) return newEnd.getMillis() - start.getMillis(); else return TWENTY_FOUR_HOURS - (start.getMillis() - newEnd.getMillis()); } /** * Check whether date is before given period. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date - date to be checked * @param start - begin of period * @param end - end of period * @return true if date is before a period; false otherwise */ public boolean beforePeriodDayTime(DateTime date, DateTime start, DateTime end) { if (date == null) return false; if (start == null) return false; if (end == null) return beforeDayTime(date, start); //date is not before start if(!beforeDayTime(date, start)) return false; //end of period is next day if(afterDayTime(start, end)) if(!afterDayTime(date, end)) return false; return true; } /** * Check whether a period, whose length is given by duration, is within a period * defined by start and end. * @param date - date to be checked * @param duration - duration of a period to be checked * @param start - begin of period * @param end - end of period * @return true if a period is within the period ; false otherwise */ public boolean withinPeriod(DateTime date, long duration, DateTime start, DateTime end) { if (date == null) return false; if (start == null || end == null) return true; if (date.isBefore(start) || (date.getMillis() + duration + timeDelta > end.getMillis())) return false; return true; } /** * Check whether a period, whose length is given by duration, is within a period * defined by start and end. * @param duration - duration of a period to be checked * @param start - begin of period * @param end - end of period * @return true if a period is within the period ; false otherwise */ public boolean withinPeriod(long duration, DateTime start, DateTime end) { if (start == null || end == null) return true; if (start.getMillis() + duration + timeDelta > end.getMillis()) return false; return true; } /** * Check whether date is within a period * defined by start and end. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date - date to be checked * @param start - begin of period * @param end - end of period * @return true if date is within the period ; false otherwise */ public boolean withinPeriodDayTime(DateTime date, DateTime start, DateTime end) { if (date == null) return false; if (start == null && end == null) return false; if (start == null) return !afterDayTime(date, end); if (end == null) return !beforeDayTime(date, start); if (afterDayTime(start, end)){ if (beforeDayTime(date, start) && afterDayTime(date, end)) return false; } else { if (beforeDayTime(date, start) || afterDayTime(date, end)) return false; } return true; } /** * Check whether a period, whose length is given by duration, is within a period * defined by start and end. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date - date to be checked * @param duration - duration of a period to be checked * @param start - begin of period * @param end - end of period * @return true if a period is within the period ; false otherwise */ public boolean withinPeriodDayTime(DateTime date, long duration, DateTime start, DateTime end) { if (date == null) return false; if (start == null && end == null) return true; if (start == null) return !afterDayTime(date, duration, end); if (end == null) return !beforeDayTime(date, duration, start); if (afterDayTime(start, end)){ if (beforeDate(date, start) && afterDayTime(date, duration, end)) return false; } else { if (beforeDate(date, start) || afterDayTime(date, duration, end)) return false; } return true; } /** * Check whether a period, whose length is given by duration, overlaps a period * defined by start and end. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date - date to be checked * @param duration - duration of a period to be checked * @param start - begin of period * @param end - end of period * @return true if a period overlaps with the period ; false otherwise */ public boolean overlapPeriodDayTime(DateTime date, long duration, DateTime start, DateTime end) { if (date == null) return false; if (start == null && end == null) return true; if (start == null) return beforeDayTime(date, end); if (end == null) return !beforeDayTime(date, duration, start); if (afterDayTime(start, end)){ if (!beforeDate(date, end) && !afterDayTime(date, duration, start)) return false; } else { if (!beforeDate(date, end) || !afterDayTime(date, duration, start)) return false; } return true; } /** * Check whether date is after given period. Only time is taken into account, i.e. * hour, minute, second, milis (without year, month, and day) * @param date - date to be checked * @param start - begin of period * @param end - end of period * @return true if date is after a period; false otherwise */ public boolean afterPeriodDayTime(DateTime date, DateTime start, DateTime end) { if (date == null) return false; if (end == null) return false; if (start == null) return afterDayTime(date, end); //date is not after end if (!afterDayTime(date, end)) return false; //end of period is next day if (afterDayTime(start, end)) if (!beforeDate(date, start)) return false; return true; } //end of operations on periods //Operations on lists of dates /** * Find date in list of dates * @param date - date to be found * @param days - Vector containing Calendar objects * @return true if data is found; false otherwise */ public boolean findDate(DateTime date, ArrayList days) { if (days == null) return false; for (int i=0; i < days.size(); i++) { DateTime vDate = days.get(i); if (!sameDate(date, vDate)) continue; return true; } return false; } /** * Find the latest date in inclDates that is not found in exclDates * @param inclDates * @param exclDates * @return the latest date */ public DateTime findLatestDate(ArrayList inclDates, ArrayList exclDates) { if (inclDates == null) return null; DateTime latest = new DateTime(); //Calendar.getInstance(); for (int i=0; i < inclDates.size(); i++) if (beforeDate(latest, inclDates.get(i))) if (!findDate(inclDates.get(i), exclDates)) latest = inclDates.get(i); return latest; } //end of operations on lists of dates /** * Get DateTime object representing current time * This method can be overloaded to return logic time, e.g. in simulations * @return current time */ public DateTime getTime() { return new DateTime(); } }