<?xml version="1.0" encoding="ISO-8859-1"?> | |
<document> | |
<properties> | |
<title>Java date and time API - Period</title> | |
<author>Stephen Colebourne</author> | |
</properties> | |
<body> | |
<section name="Period"> | |
<p> | |
A <i>period</i> in Joda-Time represents a period of time defined in terms of fields, | |
for example, 3 years 5 months 2 days and 7 hours. | |
This differs from a <a href="key_duration.html">duration</a> in that it is inexact in terms of milliseconds. | |
A period can only be resolved to an exact number of milliseconds by specifying the | |
<a href="key_instant.html">instant</a> (including chronology and time zone) it is relative to. | |
</p> | |
<p> | |
Periods do not have a <a href="key_chronology.html">chronology</a> or time zone. | |
They can be added to an <a href="key_instant.html">instant</a>, or to either | |
end of an interval to change those objects. | |
In datetime maths you could say: | |
<source> | |
instant + period = instant | |
</source> | |
</p> | |
<p> | |
For example, consider a period of 1 month. | |
If you add this period to the 1st February (ISO) then you will get the 1st March. | |
If you add the same period to the 1st March you will get the 1st April. | |
But the duration added (in milliseconds) in these two cases is very different. | |
</p> | |
<p> | |
As a second example, consider adding 1 day at the daylight savings boundary. | |
If you use a period to do the addition then either 23 or 25 hours will be added as appropriate. | |
If you had created a duration equal to 24 hours, then you would end up with the wrong result. | |
</p> | |
<p> | |
The Joda-Time library defines two types of implementation of the period concept. | |
The first type can only store a single-field, such as days or hours, but not both. | |
The second type can store any-field, expressing a value such as 5 months 8 days and 7 hours. | |
</p> | |
<subsection name="Single field Periods"> | |
<p> | |
The first type, single-field periods, is new to version 1.4 of Joda-Time. | |
These classes - <code>Years</code>, <code>Months</code>, <code>Weeks</code>, | |
<code>Days</code>, <code>Hours</code>, <code>Minutes</code>, <code>Seconds</code> - | |
all follow a very similar design, and only store the single field as implied by | |
their name. Thus a <code>Days</code> object can only store a number of days. | |
</p> | |
<p> | |
These classes can be useful when you want to write an API that must specifically take | |
in a period measured in a particular unit. For example, a travel website where you are | |
given the option of travelling ±1 days or ±3 days could store this | |
information in a <code>Days</code> object. | |
</p> | |
<p> | |
These classes provide static factory methods rather than constructors. | |
For <code>Days</code> these include <code>daysBetween(startDate, endDate)</code> to | |
obtain the number of whole days between two dates or datetimes, and | |
<code>daysIn(interval)</code> to obtain the number of whole days in an interval. | |
In addition, there are a range of constants, such as <code>Days.ZERO</code> and | |
<code>Days.ONE</code>. The factory method <code>days(int)</code> either returns | |
a constant, or creates a new instance as appropriate. | |
</p> | |
<p> | |
The single-field classes include basic mathemaical operator support. | |
For <code>Days</code> this includes <code>plus(int)</code>, <code>plus(Days)</code>, | |
<code>multipliedBy(int)</code>, <code>dividedBy(int)</code> and <code>negated()</code>. | |
All operations return a new instance, as <code>Days</code> is immutable. | |
The single-field classes are also comparable. | |
</p> | |
<p> | |
Converting between different types of period is a difficult problem. | |
One day is not always equal to 24 hours. (It might be 23 or 25 at daylight savings time change.) | |
However, many applications have business rules that assume a 24 hour day and so on. | |
To support this, <code>Days</code> has methods named <code>toStandardHours()</code> and | |
so on which convert the number of days to a number of hours assuming a 24 hour day. | |
The word 'standard' is being specifically used in the method name to remind users of the assumption. | |
</p> | |
</subsection> | |
<subsection name="Any field Periods"> | |
<p> | |
The second type of period is the any-field period. | |
These are implemented by the <code>Period</code> and <code>MutablePeriod</code> classes. | |
Internally, they store a set of <code>int</code> fields, one for each field. | |
The standard set of fields in a period are years, months, weeks, days, hours, minutes, seconds and millis. | |
The <a href="apidocs/org/joda/time/PeriodType.html">PeriodType</a> class allows this set | |
of fields to be restricted, for example to elimate weeks. | |
This is significant when converting a duration or interval to a period, as the calculation | |
needs to know which period fields it should populate. | |
</p> | |
<p> | |
The <code>Period</code> class is useful when you want to write an API that can take | |
a period that probably contains more than one field. However, to be even more general, | |
your API could define itself to accept a <code>ReadablePeriod</code>, and then the | |
calling code could pass in either a <code>Period</code> or a single field period like | |
<code>Days</code>. | |
</p> | |
<p> | |
Methods exist on <code>Period</code> to obtain each field value. | |
There are also methods to change a field value, such as <code>withDays(int)</code>. | |
They are named 'with' as they return a new <code>Period</code> object, due to immutability. | |
</p> | |
<p> | |
You cannot compare any-field periods for order, as there is no sensible comparison strategy. | |
Instead, you need to convert the period to a <code>Duration</code> based on a specific date | |
and then compare the duration. | |
</p> | |
</subsection> | |
</section> | |
<section name="Using Periods in Joda-Time"> | |
<p> | |
Within Joda-Time a period is represented by the | |
<a href="apidocs/org/joda/time/ReadablePeriod.html">ReadablePeriod</a> interface. | |
There are nine implementations of the interface provided: | |
<ul> | |
<li><a href="apidocs/org/joda/time/Period.html">Period</a> - | |
An immutable implementation</li> | |
<li><a href="apidocs/org/joda/time/MutablePeriod.html">MutablePeriod</a> - | |
A mutable implementation</li> | |
<li><a href="apidocs/org/joda/time/Years.html">Years</a> - | |
An immutable years-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Months.html">Months</a> - | |
An immutable months-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Weeks.html">Weeks</a> - | |
An immutable weeks-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Days.html">Days</a> - | |
An immutable days-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Hours.html">Hours</a> - | |
An immutable hours-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Minutes.html">Minutes</a> - | |
An immutable minutes-only implementation</li> | |
<li><a href="apidocs/org/joda/time/Seconds.html">Seconds</a> - | |
An immutable seconds-only implementation</li> | |
</ul> | |
We recommend the immutable implementation for general usage. | |
</p> | |
<p> | |
The code can be used in various ways: | |
<source> | |
DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0); | |
DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0); | |
// period of 1 year and 7 days | |
Period period = new Period(start, end); | |
// calc will equal end | |
DateTime calc = start.plus(period); | |
// able to calculate whole days between two dates easily | |
Days days = Days.daysBetween(start, end); | |
// able to calculate whole months between two dates easily | |
Months months = Months.monthsBetween(start, end); | |
</source> | |
</p> | |
<p> | |
Note that the interface <code>ReadablePeriod</code> should not be used like the collections API. | |
The interface only contains the core subset of the operations. | |
Instead, you should usually refer directly to the implementation classes in your APIs. | |
</p> | |
<subsection name="Nulls"> | |
<p> | |
Joda-Time defines a null period as a zero length period. | |
Thus, when a method is defined as taking a <code>ReadablePeriod</code>, passing null in | |
will be the same as passing in a zero length period. | |
</p> | |
</subsection> | |
</section> | |
</body> | |
</document> |