<?xml version="1.0" encoding="ISO-8859-1"?> | |
<document> | |
<properties> | |
<title>Java date and time API - FAQ</title> | |
<author>Stephen Colebourne</author> | |
<author>Brian S O'Neill</author> | |
</properties> | |
<body> | |
<section name="Frequently Asked Questions"> | |
<p> | |
Some common questions about Joda-Time are answered here. | |
<ul> | |
<li><a href="#illegalinstant">What does "Illegal instant due to time zone offset transition" mean?</a></li> | |
<li><a href="#rulesoutofdate">Are the time-zone rules are out of date?</a></li> | |
<li><a href="#newzonerules">Does Joda-Time support the 2007 US and Canada time zone rules?</a></li> | |
<li><a href="#wrongoffset">Why is the offset for a time-zone different to the JDK?</a></li> | |
<li><a href="#datediff">How do I calculate the difference between two dates?</a></li> | |
<li><a href="#iso">What is ISO8601?</a></li> | |
<li><a href="#default">Why is ISO8601 the default?</a></li> | |
<li><a href="#internalstorage">How are times calculated internally?</a></li> | |
<li><a href="#long">Why limit to the number of milliseconds in a long?</a></li> | |
<li><a href="#range">What date range is supported?</a></li> | |
<li><a href="#submilli">What about sub-millisecond accuracy?</a></li> | |
<li><a href="#performance">How well does it perform?</a></li> | |
<li><a href="#threading">Does it support multi-threading?</a></li> | |
<li><a href="#leapseconds">Are leap seconds supported?</a></li> | |
<li><a href="#numberclasses">There are lots of classes, do I need to learn them all?</a></li> | |
<li><a href="#tzreimplement">Why reimplement TimeZone?</a></li> | |
<li><a href="#joda">What is with the name 'joda'?</a></li> | |
<li><a href="#pronounce">How do you pronounce 'joda'?</a></li> | |
</ul> | |
Question not answered? Suggest one via the <a href="mail-lists.html">mailing list</a>.<br></br> | |
</p> | |
<a name="illegalinstant" /> | |
<subsection name="What does 'Illegal instant due to time zone offset transition' mean?"> | |
<p> | |
Joda-Time only allows the key classes to store valid date-times. | |
For example, 31st February is not a valid date so it can't be stored (except in <code>Partial</code>). | |
</p> | |
<p> | |
The same principle of valid date-times applies to daylight savings time (DST). | |
In many places DST is used, where the local clock moves forward by an hour in spring and back by an hour in autumn/fall. | |
This means that in spring, there is a "gap" where a local time does not exist. | |
</p> | |
<p> | |
The error "Illegal instant due to time zone offset transition" refers to this gap. | |
It means that your application tried to create a date-time inside the gap - a time that did not exist. | |
Since Joda-Time objects must be valid, this is not allowed. | |
</p> | |
<p> | |
Possible solutions may be as follows:<br /> | |
Use <code>LocalDateTime</code>, as all local date-times are valid.<br /> | |
When converting a <code>LocalDate</code> to a <code>DateTime</code>, then use <code>toDateTimeAsStartOfDay()</code> | |
as this handles and manages any gaps.<br /> | |
When parsing, use <code>parseLocalDateTime()</code> if the string being parsed has no time-zone. | |
</p> | |
<p> | |
Not all cases of this error have a simple solution. | |
Hopefully this FAQ has explained what the error means allowing you to work out what the correct solution will be. | |
</p> | |
</subsection> | |
<a name="rulesoutofdate" /> | |
<subsection name="Are the time-zone rules are out of date?"> | |
<p> | |
Joda-Time releases only occur infrequently. | |
But time-zone changes happen all the time. | |
As such, it may well be that the rules are out of date. | |
</p> | |
<p> | |
Between the Joda-Time releases, it is your responsibility to update the jar file with the latest time-zone rules. | |
You must update <i>both</i> the JDK and Joda-Time rules to the same version at the same time to avoid problems. | |
See the <a href="tz_update.html">update time-zone rules guide</a> for more details. | |
</p> | |
</subsection> | |
<a name="newzonerules" /> | |
<subsection name="Does Joda-Time support the 2007 US and Canada time zone rules?"> | |
<p> | |
The time zone rules occur in three key places, your operating system, the JDK and Joda-Time. | |
To be sure of hitting no issues, you should ensure that all three of these have been updated. | |
</p> | |
<p> | |
Version 1.5 of Joda-Time contains all the daylight savings rule updates for the 2007 US change. | |
For earlier versions of Joda-Time the situation is more complex: | |
</p> | |
<p> | |
If your application only uses the major time zones of the US, then you need Joda-Time 1.2 or later. | |
If your application also uses the major time zones of the Canada, then you need Joda-Time 1.2.1 or later. | |
If your application uses the minor time zones of the US or Canada, then you need Joda-Time 1.4 or later. | |
For Bermuda (Atlantic/Bermuda) you need Joda-Time 1.4 or later. | |
For the Bahamas (America/Nassau) you need Joda-Time 1.5. | |
</p> | |
<p> | |
For any future, or similar time zone change, you can upgrade your Joda-Time jar by following <a href="tz_update.html">these instructions</a>. | |
</p> | |
</subsection> | |
<a name="wrongoffset" /> | |
<subsection name="Why is the offset for a time-zone different to the JDK?"> | |
<p> | |
There are two main reasons for this. | |
</p> | |
<p> | |
The first reason is that both the JDK and Joda-Time have time-zone data files. | |
It is important to keep both up to date and in sync if you want to compare the offset between the two. | |
</p> | |
<p> | |
The second reason affects date-times before the modern time-zone system was introduced. | |
The time-zone data is obtained from the <a href="http://www.iana.org/time-zones">time-zone database</a>. | |
The database contains information on "Local Mean Time" (LMT) which is the local time that would have been | |
observed at the location following the Sun's movements. | |
</p> | |
<p> | |
Joda-Time uses the LMT information for all times prior to the first time-zone offset being chosen in a location. | |
By contrast, the JDK ignores the LMT information. | |
As such, the time-zone offset returned by the JDK and Joda-Time are different for date-times before the modern time-zone system. | |
</p> | |
</subsection> | |
<a name="datediff" /> | |
<subsection name="How do I calculate the difference between two dates?"> | |
<p> | |
This question has more than one answer! | |
If you just want the number of whole days between two dates, then you can use the | |
new <a href="apidocs/org/joda/time/Days.html">Days</a> class | |
in version 1.4 of Joda-Time. | |
<source> | |
Days d = Days.daysBetween(startDate, endDate); | |
int days = d.getDays(); | |
</source> | |
This method, and other static methods on the <code>Days</code> class have been | |
designed to operate well with the JDK5 static import facility. | |
</p> | |
<p> | |
If however you want to calculate the number of days, weeks, months and years between | |
the two dates, then you need a <a href="apidocs/org/joda/time/Period.html">Period</a> | |
By default, this will split the difference between the two datetimes into parts, | |
such as "1 month, 2 weeks, 4 days and 7 hours". | |
<source> | |
Period p = new Period(startDate, endDate); | |
</source> | |
You can control which fields get extracted using a | |
<a href="apidocs/org/joda/time/PeriodType.html">PeriodType</a>. | |
<source> | |
Period p = new Period(startDate, endDate, PeriodType.yearMonthDay()); | |
</source> | |
This example will return not return any weeks or time fields, thus the previous | |
example becomes "1 month and 18 days". | |
</p> | |
<p> | |
For more info, consult the <a href="key_period.html">period guide</a>. | |
</p> | |
</subsection> | |
<a name="iso" /> | |
<subsection name="What is ISO-8601?"> | |
<p> | |
Historically, every country has found their own solution to measuring time. | |
This has often been political and religious. | |
To simplify the problem, especially in the realm of computer data transfer, the | |
<a href="cal_iso.html">ISO-8601</a> standard was founded. | |
</p> | |
<p> | |
The ISO standard defines a framework for passing dates and times between computer systems in a standard way. | |
The standard uses the proleptic Gregorian calendar. | |
This makes it fully compatible with the calendar system used in most of the world after 1582. | |
The standard warns that it may only be used to represent dates before 1582 'by mutual agreement'. | |
</p> | |
<p> | |
The standard defines twelve months January to December numbered 1 to 12 and | |
seven days Monday to Sunday, numbered 1 to 7. | |
In addition it defines the first week of the year as the first week to have most of its days in the new year. | |
This can result in the first week of a year starting in the previous year and the last week ending in the following year. | |
</p> | |
<p> | |
The key point about ISO-8601 is that it is a framework for dates not an absolute single definition. | |
The most common form is YYYY-MM-DDTHH:MM:SS.SSSZ, in other words year-month-day letter 'T' hour:minute:second and fractions. | |
</p> | |
</subsection> | |
<a name="default" /> | |
<subsection name="Why is ISO8601 the default?"> | |
<p> | |
Dates and times can be a localization nightmare (or should that be localisation...). | |
Often political, geographic and religious factors have come into play. | |
We wanted to avoid these factors if possible. | |
</p> | |
<p> | |
The ISO8601 standard is a good choice because it is a standard designed for computer | |
data transfer and developed by a standards body. It is also a good choice because it | |
is compatible with the calendar system used by most businesses worldwide today. | |
Finally, it is a good choice as it forces API users to think about the decision they | |
make if they require non-ISO or historically accurate calendar systems. | |
</p> | |
</subsection> | |
<a name="internalstorage" /> | |
<subsection name="How are times calculated internally?"> | |
<p> | |
The main time interface is <a href="apidocs/org/joda/time/ReadableInstant.html">ReadableInstant</a>. | |
All classes that implement this interface, such as <code>DateTime</code>, | |
store time as a single long value representing milliseconds. | |
The epoch of the definition is 1970-01-01T00:00:00Z, which is the same as the JDK time definition and usage. | |
Querying a field, such as year or hour, will calculate the value from the millisecond instant. | |
</p> | |
<p> | |
A secondary time interface is <a href="apidocs/org/joda/time/ReadablePartial.html">ReadablePartial</a>. | |
Classes implementing this interface store data in two ways. The 'local' classes, such as <code>LocalDate</code> | |
and <code>LocalTime</code> store the number of milliseconds from 1970 without a time zone. | |
All other implementations, such as <code>YearMonthDay</code> and <code>TimeOfDay</code>, | |
store time as a one int value for each field. | |
</p> | |
</subsection> | |
<a name="long" /> | |
<subsection name="Why limit to the number of milliseconds in a long?"> | |
<p> | |
There are three main reasons for using a single long value to store the time. | |
<ol> | |
<li>Compatibility - being compatible with the JDK makes conversion simpler</li> | |
<li>Performance - a primitive value enables fast calculations, | |
whereas alternatives generally involve lots of expensive object creation</li> | |
<li>Big enough - the range provided by a millisecond based solution is big enough for most needs</li> | |
</ol> | |
</p> | |
</subsection> | |
<a name="range" /> | |
<subsection name="What date range is supported?"> | |
<p> | |
The range supported is -292,269,054 to 292,277,023. | |
In other words, roughly +/- 290 million years to millisecond precision. | |
</p> | |
<p> | |
If you want a date outside this range, ask yourself if you really want millisecond precision. | |
In reality, dates this far in the past or future should only be stored as years - | |
anything else is meaningless. | |
</p> | |
</subsection> | |
<a name="submilli" /> | |
<subsection name="What about sub-millisecond accuracy?"> | |
<p> | |
Joda-Time does not support accuracy of times below millisecond. | |
Physics defines time scales down to 5E-44 secs. | |
The only way to accurately record these sorts of times is using the BigInteger class. | |
This would severely compromise the performance of the whole API for a very limited use. | |
</p> | |
</subsection> | |
<a name="performance" /> | |
<subsection name="How well does it perform?"> | |
<p> | |
Joda-Time is designed for performance. Compared to java.util.Calendar, | |
java.text.SimpleDateFormat, and java.util.TimeZone, nearly all equivalent | |
operations in Joda-Time are faster. The significant exceptions are operations | |
to get or set an individual field. | |
</p> | |
<p> | |
Calling "get" on java.util.Calendar is very fast because it doesn't do any | |
work. Calendar calculates all fields in advance, even if many of those fields | |
you won't need. Calendar's set method is fast because it defers calculations | |
until later. Calling Calendar.get after calling Calendar.set forces all the | |
field values to be re-calculated. Calling Joda's DateTime.get method after | |
calling DateTime.set only performs the minimum amount of calculations, and the | |
pair is faster than Calendar. | |
</p> | |
<p> | |
Joda-Time also allocates very few temporary objects during operations, and | |
performs almost no thread synchronization. In systems that are heavily | |
multi-threaded or use a lot of memory, Calendar, SimpleDateFormat, and TimeZone | |
can become bottlenecks. When the Joda-Time classes are used instead, the | |
bottlenecks go away. | |
</p> | |
</subsection> | |
<a name="threading" /> | |
<subsection name="Does it support multi-threading?"> | |
<p> | |
Every public class in Joda-Time is documented as being thread-safe or not. | |
Joda-Time makes heavy use of the immutability design pattern, and all immutable | |
classes in Joda-Time are thread-safe. Many mutable classes whose instances are | |
not likely to be shared are not thread-safe, and are documented as such. | |
</p> | |
<p> | |
The most common multi-threading mistake made by Java programmers is in the use | |
of SimpleDateFormat. Calling its format method on a shared instance by | |
concurrent threads can produce bizarre results. All of Joda-Time's formatting | |
classes are thread-safe and immutable. | |
</p> | |
</subsection> | |
<a name="leapseconds" /> | |
<subsection name="Are leap seconds supported?"> | |
<p> | |
Joda-Time does not support leap seconds. Leap seconds can be supported by | |
writing a new, specialized chronology, or by making a few enhancements to the | |
existing ZonedChronology class. In either case, future versions of Joda-Time | |
will not enable leap seconds by default. Most applications have no need for it, | |
and it might have additional performance costs. | |
</p> | |
</subsection> | |
<a name="numberclasses" /> | |
<subsection name="There are lots of classes, do I need to learn them all?"> | |
<p> | |
No, you only need to learn a small subset of the classes in the API. | |
The javadoc clearly indicates which packages contain user classes, and which contain | |
implementation classes. | |
In addition, there are a large number of package scoped classes, which are hidden | |
in the javadoc view anyway. | |
Most applications will not need to directly import, extend or implement classes in | |
the implementation packages. | |
Basically, the API consists of the main package, plus the formatting package. | |
</p> | |
</subsection> | |
<a name="tzreimplement" /> | |
<subsection name="Why reimplement TimeZone?"> | |
<p> | |
The JDK TimeZone class varies in the support it can provide from one JDK release to another. | |
The rules for determining Daylight Saving Time also change frequently. | |
The Joda solution uses the international standard format for time zone rule data, | |
and allows it to be updated independently of the timing of JDK releases. | |
With perhaps 8 releases of the time zone rules per year this can be quite significant. | |
</p> | |
</subsection> | |
<a name="joda" /> | |
<subsection name="What is with the name 'joda'?"> | |
<p> | |
'Joda' is a short, four letter name, beginning with 'j' whose domain name was free. | |
It is not an acronym. | |
</p> | |
</subsection> | |
<a name="pronounce" /> | |
<subsection name="How do you pronounce 'joda'?"> | |
<p> | |
The 'J' in 'Joda' is pronounced the same as the 'J' in <a href="http://dictionary.reference.com/browse/Java">'Java'</a>. | |
The project is not capable of wielding a <a href="http://en.wikipedia.org/wiki/Yoda">light saber</a> and is thus pronounced differently. | |
</p> | |
<p> | |
<br /> | |
</p> | |
</subsection> | |
</section> | |
</body> | |
</document> |