/* Copyright (c) 2006 Google Inc. * * 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 com.google.api.gbase.client; import com.google.gdata.data.DateTime; /** * A date or date/time range, with a start and end {@link DateTime}. * * Since <code>dateTimeRange</code> is a superclass of <code>date</code> * and <code>dateTime</code>, a DateTimeRange object can sometimes be * used to represent a single date or dateTime. When this is the case, * the start and end value will be identical and {@link #isDateTimeOnly()} * will return true. You can then get the {@link DateTime} the 'range' * corresponds to using {@link #toDateTime()}. */ public class DateTimeRange { /** * The start date/time of this range. */ private final DateTime start; /** * The end date/time of this range. */ private final DateTime end; /** * Creates a new range. * * @param start * @param end * @exception IllegalArgumentException if either start or end is null */ public DateTimeRange(DateTime start, DateTime end) { assertArgumentNotNull(start, "start"); assertArgumentNotNull(end, "end"); this.start = start; this.end = end; } /** * Creates a new range that is actually a date or a dateTime. * * Empty ranges (with start date the same as the end dates) can * be detected using {@link #isDateTimeOnly()} and then converted * using {@link #toDateTime()}. * * @param dateTime */ public DateTimeRange(DateTime dateTime) { this(dateTime, dateTime); } /** * Checks whether this is a real range, with a start and an * end date, or a date/dateTime posing as a range. * * This hack is necessary to handle treating DateTime as * a DateTimeRange, because dateTimeRange is a supertype of * date and dateTime. * * If this method returns true, you can get the {@link DateTime} * object this object corresponds to using {@link #toDateTime()} * * @return true if start is the same as end */ public boolean isDateTimeOnly() { return start.equals(end); } /** * Converts empty ranges into {@link DateTime}. * * @return a DateTime object * @exception IllegalStateException if the start and end date are * distinct, which means the dateTimeRange is neither a date * nor a dateTime (see {@link #isDateTimeOnly()}) */ public DateTime toDateTime() { if (!isDateTimeOnly()) { throw new IllegalStateException("This is a valid range, with distinct " + "start and end date. It cannot be converted to one DateTime value. " + "(Check with isDateTimeOnly() first): " + this); } return start; } private void assertArgumentNotNull(Object object, String name) { if (object == null) { throw new NullPointerException(name + " should not be null"); } } /** * Gets the start date or date+time. */ public DateTime getStart() { return start; } /** * Gets the end date or date/time. */ public DateTime getEnd() { return end; } /** * Returns the canonical string representation for a range, as used * in the XML (start " " end). */ @Override public String toString() { return start + " " + end; } @Override public int hashCode() { return 37 * start.hashCode() + end.hashCode(); } @Override public boolean equals(Object o) { if (!(o instanceof DateTimeRange)) { return false; } else { DateTimeRange other = (DateTimeRange)o; return other.start.equals(start) && other.end.equals(end); } } }