public final class DayRangePeriod extends Period implements java.io.Serializable
Period
that is defined explicitly in terms of the range of
days that it covers.
DayRangePeriod
in the context of a Breakdown
If the boundaries of a DayRangePeriod
line up neatly with the
date splitting of a Breakdown
that contains it, then the calculated
data will cover the specified range exactly (or a subset of that range if
there isn't enough data to satisfy the request fully). This will always be
the case if the period is contained within a DailyBreakdown
.
If you put a DayRangePeriod
inside a WeeklyBreakdown
,
MonthlyBreakdown
, YearlyBreakdown
, or
FullYearsAverageBreakdown
, then it is up to you whether you ensure
that the boundaries of your period line up neatly with the
weekly/monthly/yearly splitting of the breakdown. If your period specifies
dates that do line up with the breakdown, then those dates will be
treated as an exact specification. If your period specifies dates that
don't line up with the breakdown, the API will effectively widen the
range (at the beginning, or the end, or both boundaries if necessary) to
ensure that the returned data covers all the dates that your range specifies
(assuming enough data exists to do this).
The following examples should help to make this clearer:
DayRangePeriod period =
new DayRangePeriod(Day.of(2010, 10, 19).to(2010, 11, 5));
DatedBreakdown breakdown = new MonthlyBreakdown(period);
In this example you can see that the dates of the period (2010-10-19 to
2010-11-05) do not match up with the calendar months that the
MonthlyBreakdown
specifies. In this instance the API would widen
the range at both the beginning and the end, attempting to return one monthly
value for October 2010 and one for November 2010.
If the first day of the specified period was the first day of a breakdown month (e.g. 2010-10-01), the range would not have been widened at the start. Similarly, if the last day of the specified period was the last day of a breakdown month (e.g. 2010-11-30), the range would not have been widened at the end. Widening only occurs when the dates don't line up with the splitting of the breakdown.
Day singleDay = Day.of(2009, 7, 21);
DayRangePeriod period = new DayRangePeriod(singleDay.to(singleDay));
DatedBreakdown breakdown = new YearlyBreakdown(period);
In this example the period is specified to cover just one day: 2009-07-21. Of course, that period, if interpreted explicitly, is not long enough to allow a yearly breakdown.
In this instance the API would widen the range at the beginning and the end, giving 2009-01-01 to 2009-12-31, so that it could return a yearly value for 2009 (the year containing the specified range).
DayRangePeriod
object, that object will
always contain the exact dates that you specified. Widening can only happen
when those dates are being interpreted as part of the data-assembly process.DayRangePeriod
as part of a request for 12 months of monthly
data (e.g. calendar months from 2009-01-14 to 2010-01-13), widening could
push that to 13 months (e.g. 2009-01-01 to 2010-01-31), pushing you closer
towards your rate limit than you would have wanted. This can't happen if you
specify your dates precisely or use LatestValuesPeriod
instead of
DayRangePeriod
.Instances of this class are immutable. You can safely reuse them and call them from multiple threads at once.
Constructor and Description |
---|
DayRangePeriod(DayRange dayRange)
Constructs a
DayRangePeriod object that specifies the period
covered by dayRange . |
Modifier and Type | Method and Description |
---|---|
DayRange |
dayRange()
Returns the non-null
DayRange object that specifies the
day(s) that this period covers. |
DayRange |
getMinimumDayRange()
Returns the non-null minimum day range that was specified using
withMinimumDayRange(net.degreedays.time.DayRange) , or throws an
IllegalStateException if no such range was specified (check
hasMinimumDayRange() before calling this). |
boolean |
hasMinimumDayRange()
Returns
true if this DayRangePeriod specifies
the day(s) that must be covered by any data returned in response
to a request for data covering this DayRangePeriod . |
java.lang.String |
toString()
Returns a non-null, non-empty string representation of this object for logging and debugging purposes.
|
DayRangePeriod |
withMinimumDayRange(DayRange minimumDayRange)
Returns a new
DayRangePeriod with the same
dayRange() as this , but also specifying
minimumDayRange as the minimum range required. |
dayRange, equals, hashCode, latestValues
public DayRangePeriod(DayRange dayRange)
DayRangePeriod
object that specifies the period
covered by dayRange
.dayRange
- the range of days that the period should cover. Cannot be
null
.java.lang.NullPointerException
- if dayRange
is
null
.public DayRangePeriod withMinimumDayRange(DayRange minimumDayRange)
DayRangePeriod
with the same
dayRange()
as this
, but also specifying
minimumDayRange
as the minimum range required.
A DayRangePeriod
created through the constructor does not
have a minimum range. Without a minimum range, the API can decide what to
do if there is not enough data available to satisfy the
dayRange()
, and it will typically return what it can from
within dayRange()
. If this method is used to specify a
minimum range, then a request for data will fail unless that minimum
range can be satisfied.
The following example shows typical usage of this method:
DayRangePeriod period =
new DayRangePeriod(targetRange).withMinimumDayRange(minimumRange);
Warning: be careful with minimum ranges, particularly when defining the last day of a minimum range. The degree days for any given day will never become available until the day has finished in the location's local time-zone, and it usually takes at least a few hours more for the required temperature data to filter through the system. For stations that don't record temperatures in the early morning (this explains the high "% estimated" figures of some minor airport stations), it can consistently take 10 or so hours for the previous day's data to become available, as our system needs a usable temperature reading from today before it will calculate the degree days from yesterday. Occasionally there can also be problems that can delay the appearance of fresh data further for certain stations, and delays of up to 10 or so days are possible, albeit rare. If your system specifies a minimum range that is too restrictive, it can easily end up with no data at all when in fact there's plenty of usable data available.
That said, there are times when a minimum range with highly-restrictive dates is exactly what you want (and you'd rather get nothing than slightly less data), so don't be afraid to specify restrictive minimum ranges if you need them.
minimumDayRange
- the non-null minimum range that the returned
DayRangePeriod
object should hold.java.lang.NullPointerException
- if minimumDayRange
is
null
.java.lang.IllegalArgumentException
- if minimumDayRange
extends
earlier or later than dayRange()
.public DayRange dayRange()
DayRange
object that specifies the
day(s) that this period covers.public boolean hasMinimumDayRange()
true
if this DayRangePeriod
specifies
the day(s) that must be covered by any data returned in response
to a request for data covering this DayRangePeriod
.
If this returns true
, it is safe to call
getMinimumDayRange()
.
public DayRange getMinimumDayRange()
withMinimumDayRange(net.degreedays.time.DayRange)
, or throws an
IllegalStateException
if no such range was specified (check
hasMinimumDayRange()
before calling this).java.lang.IllegalStateException
- if this DayRangePeriod
does
not hold a minimum day range.public java.lang.String toString()
The exact details of the representation are unspecified and subject to change.
toString
in class java.lang.Object
See www.degreedays.net/api/ for more about the Degree Days.net API.
You can sign up for a Degree Days.net API account and read the integration guide that is useful and applicable whether you are using Java or not.