/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.libreplan.business.planner.limiting.entities; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.libreplan.business.workingday.EffortDuration; import org.libreplan.business.workingday.IntraDayDate; /** * * @author Diego Pino Garcia <dpino@igalia.com> * */ public class DateAndHour implements Comparable<DateAndHour> { public static DateAndHour from(LocalDate date) { if (date != null) { return new DateAndHour(date, 0); } return null; } public static DateAndHour from(IntraDayDate date) { return new DateAndHour(date.getDate(), date.getEffortDuration().getHours()); } public static DateAndHour TEN_YEARS_FROM(DateAndHour dateAndHour) { LocalDate date = dateAndHour.getDate() != null ? dateAndHour.getDate() : new LocalDate(); DateAndHour result = new DateAndHour(date, dateAndHour.getHour()); result.plusYears(10); return result; } private LocalDate date; private Integer hour; public DateAndHour(LocalDate date, Integer hour) { Validate.notNull(date); this.date = date; this.hour = hour; } public DateAndHour(DateAndHour dateAndHour) { Validate.notNull(date); this.date = dateAndHour.getDate(); this.hour = dateAndHour.getHour(); } public LocalDate getDate() { return date; } public Integer getHour() { return hour; } @Override public int compareTo(DateAndHour time) { Validate.notNull(time); int compareDate = date.compareTo(getDate(time)); return (compareDate != 0) ? compareDate : compareHour(time .getHour()); } @Override public boolean equals(Object obj) { if (obj instanceof DateAndHour) { DateAndHour other = (DateAndHour) obj; return new EqualsBuilder().append(date, other.date) .append(hour, other.hour).isEquals(); } return false; } @Override public int hashCode() { return new HashCodeBuilder().append(date).append(hour).toHashCode(); } private LocalDate getDate(DateAndHour dateAndHour) { return (dateAndHour != null) ? dateAndHour.getDate() : null; } private int compareHour(int hour) { int deltaHour = this.hour - hour; return (deltaHour != 0) ? deltaHour / Math.abs(deltaHour) : 0; } public String toString() { return date + "; " + hour; } public DateTime toDateTime() { return date.toDateTimeAtStartOfDay().plusHours(hour); } public IntraDayDate toIntraDayDate() { return IntraDayDate.create(date, EffortDuration.hours(hour)); } public static DateAndHour max(DateAndHour... dates) { dates = (DateAndHour[]) ArrayUtils.removeElement(dates, null); return dates.length > 0 ? Collections.max(Arrays.asList(dates)) : null; } public static DateAndHour min(DateAndHour... dates) { dates = (DateAndHour[]) ArrayUtils.removeElement(dates, null); return dates.length > 0 ? Collections.min(Arrays.asList(dates)) : null; } public boolean isBefore(DateAndHour dateAndHour) { return (this.compareTo(dateAndHour) < 0); } public boolean isAfter(DateAndHour dateAndHour) { return (this.compareTo(dateAndHour) > 0); } public boolean isEquals(DateAndHour dateAndHour) { return (this.compareTo(dateAndHour) == 0); } public boolean isAfter(LocalDate date) { return isAfter(DateAndHour.from(date)); } /** * Creates an {@link Iterable} that returns a lazy iterator. If * <code>end</code> is <code>null</code> it will not stop and will keep on * producing days forever */ public Iterable<LocalDate> daysUntil(final DateAndHour end) { Validate.isTrue(end == null || end.isAfter(this)); return new Iterable<LocalDate>() { @Override public Iterator<LocalDate> iterator() { return new Iterator<LocalDate>() { private LocalDate current = getDate(); @Override public boolean hasNext() { return end == null || end.isAfter(current); } @Override public LocalDate next() { LocalDate result = current; current = current.plusDays(1); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }; } public void plusYears(int years) { date = date.plusYears(years); } }