package org.activityinfo.legacy.shared.reports.model;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.bedatadriven.rebar.time.calendar.LocalDate;
import javax.xml.bind.annotation.XmlAttribute;
import java.io.Serializable;
import java.util.Date;
/**
* Defines a time period as a range of dates.
* <p/>
* The end points of the range are <em>inclusive</em>, so that a date range of
* 1-Jan-09 to 31-Jan-09 would include all events that took place at any moment
* in the month of January.
* <p/>
* The <code>DateRange</code> can be also be open on either end.
* <p/>
* Here are a few concrete examples:
* <p/>
* <table>
* <thead>
* <tr>
* <td><strong><code>minDate</code></strong></td>
* <td><strong><code>maxDate</code></strong></td>
* <td><strong>Meaning</strong></td>
* </tr>
* </thead> <tbody>
* <tr>
* <td><code>null</code></td>
* <td><code>null</code></td>
* <td>All dates</td>
* </tr>
* <tr>
* <td>1-Feb-09</td>
* <td><code>null</code></td>
* <td>All dates on or after 1-Feb-09</td>
* </tr>
* <tr>
* <td><code>null</code></td>
* <td>31-Jan-09</td>
* <td>All dates on or before 31-Jan-09 (2009 or earlier)</td>
* </tr>
* </tbody>
* </table>
*/
public final class DateRange implements Serializable {
private LocalDate minDate;
private LocalDate maxDate;
/**
* Constructs a <code>DateRange</code> bounded by <code>minDate</code> and
* <code>maxDate</code>
*
* @param minDate The minimum date to be included in this range (inclusive), or
* <code>null</code> if there is no minimum bound
* @param maxDate The maximum date to be included in this range (inclusive), or
* <code>null</code> if there is no maximum bound.
*/
public DateRange(Date minDate, Date maxDate) {
this.setMinDate(minDate);
this.setMaxDate(maxDate);
}
public DateRange(LocalDate minDate, LocalDate maxDate) {
this.setMinDate(minDate);
this.setMaxDate(maxDate);
}
/**
* Constructs a fully open date range (all dates are included).
*/
public DateRange() {
setMinDate((LocalDate) null);
setMaxDate((LocalDate) null);
}
/**
* Gets the minimum date in this range (inclusive).
*
* @return The minimum date in this range (inclusive) or <code>null</code>
* if the range has no lower bound
*/
@XmlAttribute(name = "min")
public Date getMinDate() {
return minDate == null ? null : minDate.atMidnightInMyTimezone();
}
public LocalDate getMinLocalDate() {
return minDate;
}
/**
* Sets the minimum date in this range (inclusive).
*
* @param minDate The minimum date in this range (inclusive) or
* <code>null</code> if the range has now upper bound.
*/
public void setMinDate(Date minDate) {
this.minDate = minDate == null ? null : new LocalDate(minDate);
}
public void setMinDate(LocalDate minDate) {
this.minDate = minDate;
}
/**
* Gets the maximum date in this range (inclusive).
*
* @return The maximum date in this range (inclusive) or <code>null</code>
* if the range has no upper bound.
*/
@XmlAttribute(name = "max")
public Date getMaxDate() {
return maxDate == null ? null : maxDate.atMidnightInMyTimezone();
}
public LocalDate getMaxLocalDate() {
return maxDate;
}
/**
* Sets the maximum date in this range (inclusive).
*
* @param maxDate The maximum date in this range (inclusive) or
* <code>null</code> if the range has no upper bound.
*/
public void setMaxDate(Date maxDate) {
this.maxDate = maxDate == null ? null : new LocalDate(maxDate);
}
public void setMaxDate(LocalDate maxDate) {
this.maxDate = maxDate;
}
public static DateRange intersection(DateRange a, DateRange b) {
return new DateRange(max(a.getMinDate(), b.getMinDate()), min(a.getMaxDate(), b.getMaxDate()));
}
private static Date min(Date a, Date b) {
if (a == null && b == null) {
return null;
} else if (a != null && b != null) {
return a.before(b) ? a : b;
} else if (a != null) {
return a;
} else {
return b;
}
}
private static Date max(Date a, Date b) {
if (a == null && b == null) {
return null;
} else if (a != null && b != null) {
return a.after(b) ? a : b;
} else if (a != null) {
return a;
} else {
return b;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((maxDate == null) ? 0 : maxDate.hashCode());
result = prime * result + ((minDate == null) ? 0 : minDate.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DateRange other = (DateRange) obj;
if (maxDate == null) {
if (other.maxDate != null) {
return false;
}
} else if (!maxDate.equals(other.maxDate)) {
return false;
}
if (minDate == null) {
if (other.minDate != null) {
return false;
}
} else if (!minDate.equals(other.minDate)) {
return false;
}
return true;
}
}