/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotools.util;
import java.util.Date;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import javax.measure.quantity.Duration;
import javax.measure.converter.UnitConverter;
import javax.measure.converter.ConversionException;
import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.ErrorKeys;
/**
* A range of dates.
*
* @since 2.5
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux
*/
public class DateRange extends Range<Date> {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = -6400011350250757942L;
/**
* The unit used for time representation in a date.
*/
private static final Unit<Duration> MILLISECOND = SI.MILLI(SI.SECOND);
/**
* Creates a new date range for the given dates. Start time and end time are inclusive.
*
* @param startTime The start time (inclusive), or {@code null} if none.
* @param endTime The end time (inclusive), or {@code null} if none.
*/
public DateRange(final Date startTime, final Date endTime) {
super(Date.class, clone(startTime), clone(endTime));
}
/**
* Creates a new date range for the given dates.
*
* @param startTime The start time, or {@code null} if none.
* @param isMinIncluded {@code true} if the start time is inclusive.
* @param endTime The end time, or {@code null} if none.
* @param isMaxIncluded {@code true} if the end time is inclusive.
*/
public DateRange(final Date startTime, boolean isMinIncluded,
final Date endTime, boolean isMaxIncluded)
{
super(Date.class, clone(startTime), isMinIncluded,
clone( endTime), isMaxIncluded);
}
/**
* Creates a date range from the specified measurement range. Units are converted as needed.
*
* @param range The range to convert.
* @param origin The date to use as the origin.
* @throws ConversionException if the given range doesn't have a
* {@linkplain MeasurementRange#getUnits unit} compatible with milliseconds.
*/
public DateRange(final MeasurementRange<?> range, final Date origin) throws ConversionException {
this(range, getConverter(range.getUnits()), origin.getTime());
}
/**
* Workaround for RFE #4093999 ("Relax constraint on placement of this()/super()
* call in constructors").
*/
private DateRange(final MeasurementRange<?> range, final UnitConverter converter, final long origin)
throws ConversionException
{
super(Date.class,
new Date(origin + Math.round(converter.convert(range.getMinimum()))), range.isMinIncluded(),
new Date(origin + Math.round(converter.convert(range.getMaximum()))), range.isMaxIncluded());
}
/**
* Returns a clone of the specified date.
*/
private static Date clone(final Date date) {
return (date != null) ? (Date) date.clone() : null;
}
/**
* Workaround for RFE #4093999 ("Relax constraint on placement of this()/super()
* call in constructors").
*/
private static UnitConverter getConverter(final Unit<?> source) throws ConversionException {
if (source == null) {
throw new ConversionException(Errors.format(ErrorKeys.NO_UNIT));
}
return source.getConverterTo(MILLISECOND);
}
/**
* Returns the start time.
*/
@Override
public Date getMinValue() {
return clone(super.getMinValue());
}
/**
* Returns the end time.
*/
@Override
public Date getMaxValue() {
return clone(super.getMaxValue());
}
}